Git Product home page Git Product logo

ng-csv's Introduction

ngCsv - Export to CSV using AngularJS

An AngularJS simple directive that turns arrays and objects into downloadable CSV files,

Build Status

Dependencies

  • angular.js (of course!), any version starting with 1
  • angular-sanitize.js, any version starting with 1

How to get it ?

Manual Download

Download the from here

Bower

bower install ng-csv

Npm

npm install ng-csv

CDN

ng-csv is available at cdnjs

Usage

  1. Add ng-csv.min.js to your main file (index.html). please also make sure you're adding angular-sanitize.min.js.

  2. Set ngCsv as a dependency in your module

var myapp = angular.module('myapp', ['ngSanitize', 'ngCsv'])
  1. Add ng-csv directive to the wanted element, example:
<button type="button" ng-csv="getArray" filename="test.csv">Export</button>

ngCsv attributes

  • ng-csv: The data array - Could be an expression, a value or a promise.

  • filename: The filename that will be stored on the user's computer

  • csv-header: If provided, would use this attribute to create a header row

    <button type="button" ng-csv="getArray" csv-header="['Field A', 'Field B', 'Field C']" filename="test.csv">Export</button>
  • csv-column-order: Defines the column order to be set when creating the body of the CSV (may be according to the csv-headers) - use it when you have an array of objects.

  • field-separator: Defines the field separator character (default is ,)

  • decimal-separator: Defines the decimal separator character (default is .). If set to "locale", it uses the language sensitive representation of the number.

  • text-delimiter: If provided, will use this characters to "escape" fields, otherwise will use double quotes as deafult

  • quote-strings: If provided, will force escaping of every string field.

  • lazy-load: If defined and set to true, ngCsv will generate the data string only on demand. See the lazy_load example for more details.

  • add-bom: Add the Byte Order Mark, use this option if you are getting an unexpected char when opening the file on any windows App.

  • charset: Defines the charset of the downloadable Csv file. Default is "utf-8".

  • csv-label: Defines whether or not using keys as csv column value (default is false).

Examples

You can check out this live example here: https://asafdav.github.io/ng-csv/example/

For lazy load example using promises see this example: https://asafdav.github.io/ng-csv/example/lazy_load.html

Supported Browsers

Browser Filenames
Firefox 20+ Yes
Chrome 14+ Yes
Safari No
IE 10+ Yes

Bitdeli Badge

ng-csv's People

Contributors

ada-lovecraft avatar alexilyaev avatar asafdav avatar bitdeli-chef avatar cvbuelow avatar daraliu avatar dotansimha avatar dvalentiate avatar elderbas avatar formation-sqli avatar happyminded avatar icydillic avatar isakb avatar langman66 avatar liront avatar netaisllc avatar pursual avatar scuxiayiqian avatar shaohaolin avatar skoczen avatar vinntreus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ng-csv's Issues

Set dynamic headers

It is possible to set the header with the csv-header attribute on the element. It would be realy great if it was possible to set this header on click event rather when the element is loaded in the DOM.

  1. Example
    I would like to use ng-csv as a service. Pas an object array to the service and trigger the csv document creation. But I can't do this with headers at this moment.
  2. Example
    Applications using ng-translate for language support won't be able to use the header as its unkown how to write the header when the js comes from the server. Therefor you can't hard-code the header for the "name"-column,
    eg. "Name", "Navn", "Nombre"

Is ngSanitize required?

I'm getting this error when trying to include ngCsv:

Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:modulerr] Failed to instantiate module ngCsv due to:
Error: [$injector:modulerr] Failed to instantiate module ngSanitize due to:
Error: [$i......1) angular.js:78
(anonymous function) angular.js:78
(anonymous function) angular.js:3648
forEach angular.js:303
loadModules angular.js:3614
createInjector angular.js:3554
doBootstrap angular.js:1299
bootstrap angular.js:1314
angularInit angular.js:1263
(anonymous function) angular.js:20589
trigger angular.js:2342
(anonymous function) angular.js:2613
forEach angular.js:310
eventHandler angular.js:2612

Header relating to a nested array should have col span applied

If I have the following data

[
  {
    id: 123,
    name: "some name"
    desc: "lorem ipsum"
    data: [1,2,3,4,5,6]
  }
.......
]

and then I specify csv-header="['Event ID', 'Question', 'Description', 'Answers']"

I would expect the exported csv to have a header 'Answers' which spans data.length columns. i.e. all the data sits under a single heading.

ghost column added

There is a column added to my export with "garbage data" in it. When I look the array I'm passing in, it appears clean, and does not contain this additional data in it. An example of the added data.... 29,02B,02D,02F,02H,02J and some are right justified and others left justified.

Support dynamic filename

Currently, ng-csv looks support only static filename with :filename attribute, but, I'd like to use :filename attribute as dynamic like as below:

Element

<button filename="getFilename()">

Script

$scope.getFilename() = function() {
 return "blah~blah~";
}

I use ng-csv with some fix to use like as above, and want to support this in official.

Best,

ng-click compatibility

I apologize if this is dumb. However, I'm using the directive as part of a dialog where the button to both export as csv and close the dialog is the same. on plunker ngcsv seems to ignore the ng-click. When used with angular bootstrap there are a bunch of errors. If there is a beforeExport and afterExport or some such I think that would help with compatibility.

RIght now I'm doing this.

  <div ng-csv="csvData" csv-header="colsToExport" filename="{{exportFileName}}">
    <button class="btn btn-primary" ng-click="ok()">OK</button>
  </div>

Where the div tightly wraps the button, because of event bubbling my ok method is preparing the csvData before the ngcsv sees the click basically giving me a beforeExport.

[$rootScope:inprog] $digest already in progress

Hi,

I am aware that this is a duplicate of issue #18, but I have encountered the same issue.

I am 90% sure that the error I'm seeing is because of an unfortunate interaction between angular bootstraps 'typeahead' directive and this directive. I believe that the bootstrap directive registers a click listener on the document which then calls $digest. Please see this link: https://github.com/angular-ui/bootstrap/blob/master/src/typeahead/typeahead.js#L306

I'm somewhat of an angular novice, so I have no idea what the best resolution is for this issue.

If there's anything else I can provide please let me know.

Thanks.

How do make buildCsv wait while I'm loading data asynchronously?

I'm not sure if I've setup this directive correctly or not. Can you please provide some guidance.

In my case when a user clicks the button I will fetch all my data (15,000+ rows) from a WebAPI.

I've setup my html and controller as such below:

            <button class="btn btn-default"
                    ng-csv="getArray()" csv-header="getHeader()" lazy-load="true" filename="export1.csv" field-separator=",">
                Export to CSV (Lazy Load)
            </button>

In my getArray() function I'm return a function to be called later to lazy-load my data.

    $scope.getArray = function() {
        return lazyLoadExportData;
    }

    function lazyLoadExportData() {

        var deferred = $q.defer();
        getGroupMembers()
            .then(function (data) {
                deferred.resolve(data);
            }, function (errorData) {
            deferred.reject(errorData);
        });
        return deferred.promise;
    }

Inside of ng-csv (line 118) the arrData = data() invokes my lazyLoadExportData(), but it does not wait until the lazyLoadExportData() has completed gathering all it's data when the promise is resolved.

if (angular.isArray(data))
arrData = data;
else
arrData = data();

Can you please provide an example?

Thanks so much!

It doesn't escape commas properly

If you add a string with comma inside, you'll get a wrong number of columns. For examlpe:

angular.module('csv', ['ngCsv']);

function Main($scope) {
    $scope.sample = "Sample";
    $scope.getArray = [{a: 1, b:2}, {a:3, b:"asdas,dsadas"}];                            
}

Will result:

1,2
3,asdas,dsadas

while it should be

1,2
3,"asdas,dsadas"

receiving Error: [$rootScope:inprog] $digest already in progress

issue with digest already in progress when the doClick function is called:
link[0].href = "";
link[0].click(); - Errors here
link[0].href = scope.csv;
link[0].click(); - Errors here

if I edit the code and inject $timeout and wrap the call to doClick() in a $timeout it resolves the issue:
scope.buildCsv(scope.data(), function () {
$timeout(function() {
doClick();
});
}

CSV from controller - how to specify file?

I see in issue Exporting from controller #35 (closed), how to drive the action from the controller:

I use the example code show in the issue:

//inject CSV service in your controller
$scope.getArray = [{a: 1, b:2}, {a:3, b:4}];
$scope.options = {};
$scope.options.header = ['Field A', 'Field B'];

$scope.send_email = function() {
CSV.stringify($scope.getArray, $scope.options).then(function(result){
console.log(result);
});
}

The results look correct in the console, but I don't see how I pass in the desired file name and have the file created, like I do in the method from the HTML.

BOM not working in IE

Hi,
I'm using the last version of ng-csv, which fixes IE problem but still add-bom is not working. BOM is not added to created CSV and Excel does not recognize UTF-8 encoding. Thank you.

template causes styling issue

Is it possible to remove the template that causes a different styling to occur? For ex:

<button type="button" ng-csv="getArray()" filename="test.csv">Export</button>

I expect that I would still have a button showing after rendering. But instead, I have a non-interactive black link due to the template transformation.

Specify which fields are included from object?

Is there a way to specify which fields from the input object are included in the generated csv? I have $resource objects coming back from a restful api and when I give it to ng-csv it generates an output file that includes values, following the meaningful ones, like
"function (params, success, error) {"use strict";
"if (isFunction(params)) {"
"var result = Resource[name].call(this,"
among other things, that appear to be being generated for the $create, $delete, $get, $query, $remove etc. included in every resource object 'row'.

I have a feeling that this might be addressable from another angle, but I'm too new at angular to know if there's an easy way to make regular "object" out of a "resource".

Seems that some attributes are being ignored in 0.2.3

Using these attributes: ng-csv="csv.generate()" quote-strings="true" lazy-load="true" csv-header="csv.header()" filename="timesheet.csv" it seems that the csv-header and filename attributes are being ignored.

I think the issues are here: L41 return $scope.filename || 'download.csv'; The scope isn't getting the value, as you aren't actually watching the value it's probably better to use $attrs.filename instead of $scope.filename and I think they dropped the '@' scope declaration at some point in angular 1.2 which is probably why it isn't working for me.

The other issue is here: L49 if (angular.isDefined($attrs.csvHeader)) options.header = $scope.$eval($scope.header);. I think you meant to do $scope.$parent.$eval($scope.header) as your scope option in the directive is creating a child scope.

I've found that optional attributes are generally better off not putting on the scope option of the directive and just checking for their existence via $attr.

Thanks for the module, apart from those it's worked great for me.

filename attr is not woking in Safari

Thank you for this code (ng-csv). I used it in my project.

However, in Safari, csv file is not download. It is printed in Safari browser's new tab.
Aslo in Chrome browser filename attr is not working.

(Firefox is ok)

Including JQuery causes runtime error & retains download anchor tag

When using this in a project that includes a recent version of Jquery, the directive succeeds in generating a CSV file, but fails to remove the anchor tag that is dynamically injected, and generates a runt-time error. See attached.

To reproduce:

  1. Get test HTML document from the project. (this repo/example/index.html)
  2. Add a script tab to references JQuery 2.1.x or 1.10.x.
  3. Serve the file index.html and click "Export to CSV".
  4. Use DevTools to inspect Console for error message and Elements to confirm that the anchor tag is still in the DOM.

selection_005

selection_006

Using add-bom broken?

Hi,
I tried using the add-bom option when creating a new .csv file.
The element properties look like this:

  ng-csv="dataPromise()" csv-header="header()" lazy-load="true"
  filename="test.csv" field-separator=";" add-bom="true"

When exporting the file with the "add-bom"-Option it only writes me the stringified hex-value "%ef%bb%bf" into the file. Normaly this shouldn't be the string value I guess.
I saw that there are bom-issues and they were resolved, so I don't know what I am doing wrong here.
Am I missing something?

Kind regards,
Stefan

PS: I see you changed from data uri to blob. Perhaps this is the issue?

text-delimiter not respected when array of arrays in data

Just wondering if it's a design decision or by accident that if data is an array of arrays as opposed to an array of objects, the stringifyCell function is not used on the cells?

In $scope.buildCsv:

                var dataString, infoArray;

                if (angular.isArray(row)) 
                {
                  infoArray = row;
                } 
                else 
                {
                  infoArray = [];

                  angular.forEach(row, function(field, key)
                  {
                    this.push(stringifyCell(field));
                  }, infoArray);
                }

I don't see the reason why the conditional is necessary at all. This seems to work better:

                var dataString, infoArray;

                infoArray = [];

                angular.forEach(row, function(field, key)
                {
                  this.push(stringifyCell(field));
                }, infoArray);

Exporting from controller

Hi David,

awesome directive, but I'm wondering if I can get to work it without the button, but from controller where I would trigger the creation of the csv and use the result for something else besides download?

thank you

Do some logic before download file.

Hi i need do some logic before download the file. for example. User click button download, and see modal window where he can set the custom file name. after this he click OK - and after that it run download process..

At first i think that ng-click will help. But as i can see ng-click make it`s functionality after file was downloaded.

P.S sorry for my English.

HashKey appears in CSV output

Hiya,

I'm noticing that the $$hashKey that AngularJS uses to quickly sort/filter the data structure is being included in the CSV output. I introduced one line between lines 133-137 to take it out:

angular.forEach(row, function(field, key)
                  {
                    if(key !== "$$hashKey")
                        this.push(field);
                  }, infoArray);

I'm sure you can introduce this if statement probably at a better spot that conforms to your flow.

Microsoft Excel 2010 doesn't render file with charset UTF-8

There is a bug in MS Excel where it doesn't honor the charset specified in the CSV file without a Byte Order Mark (BOM).

image

The fix is as such:
var BOM = "%ef%bb%bf";
var DATA_URI_PREFIX = "data:text/csv;charset=utf-8," + BOM;

I'd love to submit a pull request but I am unable setup the dev env to run the existing tests.

European Excel wants Semicolon-Separated-Files.

Thanks for very helpful little project!

I just ran into Excel not opening the CSV file, bur displaying it as plain text.
Turns out that european version of Excel want Comma-Separated-Files to be Semicolon-Separated-Files instead. 0_o

Maybe we can add as default or as an option 'sep=,' to the first line of the file to fix this thing.

See http://kb.paessler.com/en/topic/2293-i-have-trouble-opening-csv-files-with-microsoft-excel-is-there-a-quick-way-to-fix-this

Using a promise for header info

Hi,

I've just gotten ngCSV to work with my $resource API calls, and it's great!

Just wondering if there is a way to provide header information based on a promise as well? I would like to construct the header array based on the returned data so I don't have to hard-code the header details in my front-end.

Any help greatly appreciated!

And thanks for ng-csv!

dan

Excel (Mac 2011) does not understand UTF-8 character encoding

I know this is stictly not a CSV issue, but I assume that sooner or later we will need to have some kind of Excel oddball mode. :( . I'm getting characters like öä wrongly displayed as ö ä. But the file itself seems to be fine when opened in a text editor that understands utf-8.

IE Compatibility

Nice little directive! However, it doesn't seem to be working in internet explorer at the moment. Is there any plan to modify it to work for IE?

Missing docs on promise

I am trying to use your promise but do not see any way to use. it..

I am trying to print in an excel sheet an array of data structures that looks like :

{
fname:"somename",
lname:"somename",
email:"some string"
urls:["stringone","stringone","stringone","stringone","stringone"],
answers:["stringone","stringone","stringone","stringone","stringone"]
}

for some reason everything prints in line. I would assume that it would print out the arrays in one cell in list form...
but it does not.

Any thoughts

Uncaught Object

As soon as I add ng-csv to my project I get an uncaught object error from angular.js. I am using AngularJS 1.2.15. Is this project not working on the latest angular?

iterating in embedded arrays

I have an array of objects that have embeded arrays

I was wondering if there was a way you can put all the results of the embeded array in a list form of the excel cell....

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.