asafdav / ng-csv

Simple directive that turns arrays and objects into downloadable CSV files
MIT License
573 stars 215 forks source link

ng-csv not working with Ionic Framework #103

Closed MBenoli closed 8 years ago

MBenoli commented 9 years ago

Hello,

I am using the Ionic-Framework. I wanted to use ng-csv to export a CSV. I found out that it doesn't work with ionic because to use Ionic, I need to use the file: ionic.bundle.js

(which is a concatenation of:

Do you have any idea on how I could fix this issue?

I am looking forward to your answer,

Sam.

asafdav commented 9 years ago

I don't see how it's related to ionic.bundle, I don't think that's the reason.

On Mon, Jun 29, 2015 at 3:54 AM, MBenoli notifications@github.com wrote:

Hello,

I am using the Ionic-Framework. I wanted to use ng-csv to export a CSV. I found out that it doesn't work with ionic because to use Ionic, I need to use the file: ionic.bundle.js

(which is a concatenation of:

  • ionic.js, angular.js, angular-animate.js,
  • angular-sanitize.js, angular-ui-router.js,
  • and ionic-angular.js).

Do you have any idea on how I could fix this issue?

I am looking forward to your answer,

Sam.

— Reply to this email directly or view it on GitHub https://github.com/asafdav/ng-csv/issues/103.

MBenoli commented 9 years ago

Hello,

I understand your skepticism, I find it weird too.

Here is a plunker that illustrate the issue. Maybe there is something I do not see...

http://plnkr.co/edit/sQ1rLEZ05oL72p3L6s56?p=preview

First click on the export button (the script containing the ionic.bundle.js is in comment by default so it has no bearing). You will see that it works.

If you uncomment the first script which is the ionic.bundle.js you will see that nothing happens when you click the "Export to CSV" button. It doesn't work anymore.

Thank you for your answer,

Sam.

MT-- commented 8 years ago

I am having the same issue using Ionic framework.

alexniver commented 8 years ago

Do not use ng-csv or alasql, they totally can't work on ionic. I solved this issud today.

First, convert your json to csv string.

Second, use $cordovaFile to create you csv file on sdcard and write csv string to this file.

Code below:

function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {
        //If JSONData is not an object then JSON.parse will parse the JSON string in an Object
        var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;

        var CSV = '';    
        //Set Report title in first row or line

        CSV += ReportTitle + '\r\n\n';

        //This condition will generate the Label/Header
        if (ShowLabel) {
            var row = "";

            //This loop will extract the label from 1st index of on array
            for (var index in arrData[0]) {

                //Now convert each value to string and comma-seprated
                row += index + ',';
            }

            row = row.slice(0, -1);

            //append Label row with line break
            CSV += row + '\r\n';
        }

        //1st loop is to extract each row
        for (var i = 0; i < arrData.length; i++) {
            var row = "";

            //2nd loop will extract each column and convert it in string comma-seprated
            for (var index in arrData[i]) {
                row += '"' + arrData[i][index] + '",';
            }

            row.slice(0, row.length - 1);

            //add a line break after each row
            CSV += row + '\r\n';
        }

        if (CSV == '') {        
            alert("当前没有任何数据, 无法导出");
            return;
        }   
        return CSV;
    }

    $scope.exportItems = function() {
        var exportItemArr = new Array();
        for(var i in $scope.items) {
            var exportItem = {};
            exportItem["编码"] = $scope.items[i]["code"];
            exportItem["借用人"] = $scope.items[i]["name"];
            exportItem["数量"] = $scope.items[i]["num"];
            exportItem["借用时间"] = $scope.items[i]["createTime"];
            exportItem["是否返还"] = $scope.items[i]["isReturnedDesc"];
            exportItem["返还时间"] = $scope.items[i]["returnTime"] ? $scope.items[i]["returnTime"]: '';
            exportItemArr.push(exportItem);
        }

        var title = $scope.title + "借用报表_" + $filter('date')(new Date(), 'yyyy_MM_dd_HH_mm_ss');
        var filename = title + ".csv";
        var filePath = cordova.file.externalRootDirectory + $rootScope.filePath; //this Path created in ionicPlatform.ready
        $cordovaFile.createFile(filePath, filename, true).then(function() {
            return $cordovaFile.writeFile(filePath, filename, JSONToCSVConvertor(exportItemArr, title, true), true);
        }).then( function(result) {
            alert("导出成功, 路径为: " + $rootScope.filePath + filename);
        }, function(err) {
            alert(JSON.stringify(err));
        });
    }
asafdav commented 8 years ago

Hi @Alexniver, sounds like we can integrate your solution in, in case you're interested, I'd love to merge a pull request that adds Ionic support to ng-csv. looking forward to it.

alexniver commented 8 years ago

@asafdav yeah, I'll do it. but I don't have much time to do this(lot of work to do), it will take some time. 10.1 - 10.7 is China's big holiday. I'll make it done

asafdav commented 8 years ago

@Alexniver you're the man!

skoczen commented 8 years ago

Just a quick note that the above fix works great for native apps where $cordovaFile is loaded, but won't help cases where the same code is being deployed on desktop. There, just a silent failure.

Happy to dig in more - this would save me a ton of work re-implementing if we can get it working!

There's also a thread open in the ionic forums, but no useful info there yet. Looks like the behavior is shared with another export plugin though.

http://forum.ionicframework.com/t/csv-export-issues/4350

skoczen commented 8 years ago

Got a fix!

Two prongs here:

  1. For browser-based stuff, the PR I have over at #121 fixes it in a backwards-compatible way by wrapping the link in a <div data-tab-disabled="true"> to disable Ionic's magic tap handling (which was killing the click event).
  2. For downloads on native apps , I had good luck with patching in
window.open(window.URL.createObjectURL(blob), '_blank', 'location=yes');

It may/may not be a better solve than @Alexniver 's fix above (this only impacts a web-based dashboard in my build right now), so leaving it for him to decide and submit appropriately.

tongpq commented 8 years ago

@Alexniver,I use your code, find Chinese Disorder Code,looking forward to you!

alexniver commented 8 years ago

@tongpq em........... my code doesn't work?Because of $cordovaFile, I havn't found a clear way to set my code to ng-csv. I don't want bind ng-csv to $cordovaFile.

warden1975 commented 8 years ago

Hi, you can just add the CSV service from the ng-csv on your controller, call CSV.stringify(), create Blob type 'text/csv', write file using Cordova Plugin File and open using Cordova Plugin File Opener2.

Below are a few code snippets to give you an idea.

.controller('CSVCtrl', function($rootScope, CSV, $cordovaFile, $cordovaFileOpener2) {
    $scope.data = [{a: 1, b:2}, {a:3, b:4}];

    CSV.stringify($scope.data, [{txtDelim: '"', decimalSep: ".", label: true, fieldSep: ","}])
    .then(function(csv) { 
        $scope.csv = csv; 
    });

    var blob = new Blob([$scope.csv], {type: "text/csv"});

    var filename = "test.csv";
    var filePath = cordova.file.externalRootDirectory + $rootScope.filePath;

    $cordovaFile.createFile(filePath, filename, true).then(function() {
        $cordovaFile.writeFile(filePath, filename, blob, true);
    }).then(function(result) {
        console.log("Success: " + filePath);
    }, function(err) {
        console.log(JSON.stringify(err));
    });

    $scope.downloadCSV = function() {
        $cordovaFileOpener2.open(filePath + filename, 'text/csv')
        .then(function() { console.log('Opened'); }, function(err) { 
            console.log(JSON.stringify(err)); 
        });
    };
});
mukul-psi commented 7 years ago

Any updates how to work it on mobile devices issue raised - https://github.com/asafdav/ng-csv/issues/185

Can anyone help me out here ?

@Alexniver @asafdav