asafdav / ng-csv Goto Github PK
View Code? Open in Web Editor NEWSimple directive that turns arrays and objects into downloadable CSV files
License: MIT License
Simple directive that turns arrays and objects into downloadable CSV files
License: MIT License
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.
I would like to see something like <table include-csv-export>
and that whole table is included in the CSV file exported.
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.
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.
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.
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)
I know this isn't a bug in your project exactly, but I have had reports that on chrome windows the .csv is removed from the file name.
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
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....
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.
Does it do the inverse way?
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).
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.
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();
});
}
I have an enhancement that will export only specified data set into csv. Let me know if you want me to share the code
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.
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.
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.
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
Field separator is always comma.
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.
Can we use header from the data "downloadProjects" on csv-header instead of "['Field A', 'Field B', 'Field C', 'Field D', 'Field E']" and how do we do it?
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.
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!
Hi, thank for sharing this very usefull piece of code. Looks like in angular version 1.1.5 the compiler can't find the provider for the a html element in the template. Any thoughts on this? Thanks for the help.
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:
The rendering of the csv content stops in FireFox when the code first encounters a # character.
Only tested in FireFox 30 to date.
See the issue @ http://jsfiddle.net/z3bs2/
Pete
Hi,
You forgot to mention in the "usage" section that you also need to include "angular-sanitize" along with "ng-csv.min.js".
Cheers
Having line break characters in strings seems to malform the CSV file by adding line breaks
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?
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?
Hi,
I made a 22mb properly formatted JSON file. I'm not sure who the culprit is since it works perfectly in Firefox but not in Chrome. It crashes when I start exporting it.
Check this code I wrote - http://c0debreaker.github.io/convert.html
Thanks,
Neil
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
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);
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"
Hello,
Is it possible to defer the generation of the data at button click event ?
Thanks,
Fred.
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.
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,
Hi,
In csv a string field needs double quotes around it. If it contains any double quotes already they should be doubled.
I noted this problem as well in ng-grid-csv-export, however handily they've fixed it now. Check out their csvStringify function:
https://github.com/angular-ui/ng-grid/blob/master/plugins/ng-grid-csv-export.js
I also think their handling of booleans is a good idea.
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.
The specification says that
- Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes
But this is currently not being respected: http://jsfiddle.net/8eA6V/1/
Hi
Looks like the stringifyCell function is not used, causing an issue if the cell contains delimitted text string.
this.push(stringifyCell(field));
Regards
Chris
The current build contains the code twice. This can't be by design?
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.
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".
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?
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.