I want to save an array of objects to a CSV file, I have tried the following code based on this answer, but my code didn't work well, can you please tell me how can I fix it? thanks in advance.
<template>
<div #click="saveLogs()">save csv</div>
</template>
<script>
export default {
name: "App",
components: {},
methods: {
/****************************************
* https://stackoverflow.com/a/68146412
****************************************/
arrayToCsv(data) {
return data
.map(
(row) =>
row
.map(String) // convert every value to String
.map((v) => v.replaceAll('"', '""')) // escape double colons
.map((v) => `"${v}"`) // quote it
.join(",") // comma-separated
)
.join("\r\n"); // rows starting on new lines
},
/**************************************************************
* downloadBlob(csv, 'export.csv', 'text/csv;charset=utf-8;')
*************************************************************/
downloadBlob(content, filename, contentType) {
// Create a blob
var blob = new Blob([content], { type: contentType });
var url = URL.createObjectURL(blob);
// Create a link to download it
var pom = document.createElement("a");
pom.href = url;
pom.setAttribute("download", filename);
pom.click();
},
saveLogs() {
const myLogs = this.arrayToCsv([
{ act_id: 44, actor: "robot_arm", color: "yellow", lego: "yb1", pick: {x: 1, y: 2, z:5} },
{ act_id: 44, actor: "robot_arm", color: "yellow", lego: "yb2", pick: {x: 1, y: 2, z:5} },
]);
this.downloadBlob(myLogs, "./gui_logs.csv", "text/csv;charset=utf-8;");
console.log("Logs has been saved");
},
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
You try to do it like it's a 2D array, but it's an array of JSON objects.
Like #traynor said, read this :
Converting JSON object to CSV
You can read this too :
JSON to CSV - Javascript client side
Also consider using npm library like csv-writer (install with npm i csv-writer). You can find out an example here.
When downloading the file, I suggest you to set content-type to 'text/csv' and filename without './'. After clicking a link you should remove it like that : pom.remove()
Related
is there a way to read the style of a column or cell in excel sheet in nodejs? I'm using xlsx lib but I am okay with using any other lib that provide this info. to be precise I need to know if a column or cell is bold or not while reading it.
The 'excel.js` did good job to get style and more other functions.
Demo - get B1 and C1 cell's styles.
B1 - Arial, 12 px size, bold
C1 - Calibri, 20 px, Italic
Code
const ExcelJS = require('exceljs');
const wb = new ExcelJS.Workbook();
const fileName = 'test-style.xlsx';
wb.xlsx.readFile(fileName).then(() => {
const ws = wb.getWorksheet('Sheet1');
const b1_font = ws.getCell('B1').font
console.log(b1_font);
const c1_font = ws.getCell('C2').font
console.log(c1_font);
}).catch(err => {
console.log(err.message);
});
Result
$ node read.js
{ bold: true, size: 12, color: { theme: 1 }, name: 'Arial', family: 2 }
{
size: 20,
color: { theme: 1 },
name: 'Calibri',
family: 2,
scheme: 'minor'
}
More detail information in here
and here
I have flow.js type definition as shown below:
export type Block = {
color: {
primary: Color,
secondary: Color,
},
font-size: '16px',
font-weight: '500',
};
And I would like to create an object with not all properties defined and another one with all fields required.
So second one:
const divv: Block = {
...all fields here
}
first one (just font-size):
const divv2: Block | any = {
font-size: '17px'
}
As you can see I've used
Block | any
To declare first one divv, but intellisense will hint me all divv2 properties, but it has only one of main Block type.
How to do it correctly?
Try $Shape
Copies the shape of the type supplied, but marks every field optional.
So, it'll be:
const divv2: $Shape<Block> = {
font-size: '17px'
}
I'm extracting an array with 4 objects and each object has an array inside, from my kendo charts datasource, on my Angular project.
The data inside each sub-object varies in size, but it always includes a timestamp, and 1-5 value fields.
I need to export this array to an Excel file (.xls or .xlsx NOT CSV).
So far I managed to download the JSON as a file on its own (both .json and unformatted .xls).
I'd like for each object to be a book and in that book to have a formatting that has the timestamp in the first column, value 1 in another, and so on. The header for the columns should be timestamp, value1 name, etc (I'm translating these on the ui according to user preferences).
How can I build this type of formatted .xls file using angular? I don't know a particular good library for this, that is clear on how to use it in Angular.
Following Nathan Beck's link sugestion, I used AlaSQL. I'm getting correctly formatted columns, just need to adapt my array to have multiple worksheets.
The way we integrate alaSQL into our Angular project is by including the alasql.min.js and xlsx.core.min.js.
Then we call the alasql method in our function
$scope.export = function(){
var arrayToExport = [{id:1, name:"gas"},...];
alasql('SELECT * INTO XLSX("your_filename.xlsx",{headers:true}) FROM ?', arrayToExport);
}
EDIT: Solved the multiple worksheets issues as well. Keep in mind that when using the multiple worksheet method, you have to remove the asterisk and replace the headers: true object in the query with a question mark, passing the options in a separate array. So:
var arrayToExport1 = [{id:1, name:"gas"},...];
var arrayToExport2 = [{id:1, name:"solid"},...];
var arrayToExport3 = [{id:1, name:"liquid"},...];
var finalArray = arrayToExport1.concat(arrayToExport2, arrayToExport3);
var opts = [{sheetid: "gas", headers: true},{sheetid: "solid", headers: true},{sheetid: "liquid", headers: true}];
alasql('SELECT INTO XLSX("your_filename.xlsx",?) FROM ?', [opts, finalArray]);
You can use the XLSX library to convert JSON into XLS file and Download. Just create a service for your AngularJS application then call it as service method having below code.
I found this tutorial having JS and jQuery code but we can refer this code to use in AngularJS
Working Demo
Source link
Method
Include library
<script type="text/javascript" src="//unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
JavaScript Code
var createXLSLFormatObj = [];
/* XLS Head Columns */
var xlsHeader = ["EmployeeID", "Full Name"];
/* XLS Rows Data */
var xlsRows = [{
"EmployeeID": "EMP001",
"FullName": "Jolly"
},
{
"EmployeeID": "EMP002",
"FullName": "Macias"
},
{
"EmployeeID": "EMP003",
"FullName": "Lucian"
},
{
"EmployeeID": "EMP004",
"FullName": "Blaze"
},
{
"EmployeeID": "EMP005",
"FullName": "Blossom"
},
{
"EmployeeID": "EMP006",
"FullName": "Kerry"
},
{
"EmployeeID": "EMP007",
"FullName": "Adele"
},
{
"EmployeeID": "EMP008",
"FullName": "Freaky"
},
{
"EmployeeID": "EMP009",
"FullName": "Brooke"
},
{
"EmployeeID": "EMP010",
"FullName": "FreakyJolly.Com"
}
];
createXLSLFormatObj.push(xlsHeader);
$.each(xlsRows, function(index, value) {
var innerRowData = [];
$("tbody").append('<tr><td>' + value.EmployeeID + '</td><td>' + value.FullName + '</td></tr>');
$.each(value, function(ind, val) {
innerRowData.push(val);
});
createXLSLFormatObj.push(innerRowData);
});
/* File Name */
var filename = "FreakyJSON_To_XLS.xlsx";
/* Sheet Name */
var ws_name = "FreakySheet";
if (typeof console !== 'undefined') console.log(new Date());
var wb = XLSX.utils.book_new(),
ws = XLSX.utils.aoa_to_sheet(createXLSLFormatObj);
/* Add worksheet to workbook */
XLSX.utils.book_append_sheet(wb, ws, ws_name);
/* Write workbook and Download */
if (typeof console !== 'undefined') console.log(new Date());
XLSX.writeFile(wb, filename);
if (typeof console !== 'undefined') console.log(new Date());
Angular directive for exporting and downloading JSON as a CSV. Perform bower install ng-csv-download. Run in plunkr
var app = angular.module('testApp', ['tld.csvDownload']);
app.controller('Ctrl1', function($scope, $rootScope) {
$scope.data = {};
$scope.data.exportFilename = 'example.csv';
$scope.data.displayLabel = 'Download Example CSV';
$scope.data.myHeaderData = {
id: 'User ID',
name: 'User Name (Last, First)',
alt: 'Nickname'
};
$scope.data.myInputArray = [{
id: '0001',
name: 'Jetson, George'
}, {
id: '0002',
name: 'Jetson, Jane',
alt: 'Jane, his wife.'
}, {
id: '0003',
name: 'Jetson, Judith',
alt: 'Daughter Judy'
}, {
id: '0004',
name: 'Jetson, Elroy',
alt: 'Boy Elroy'
}, {
id: 'THX1138',
name: 'Rosie The Maid',
alt: 'Rosie'
}];
});
<!DOCTYPE html>
<html ng-app="testApp">
<head>
<meta charset="utf-8" />
<title>Exporting JSON as a CSV</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="csv-download.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div>Using an Angular directive for exporting JSON data as a CSV download.</div>
<div ng-controller="Ctrl1">
<h2>All Attributes Set</h2>
<csv-download
filename="{{data.exportFilename}}"
label="{{data.displayLabel}}"
column-header="data.myHeaderData"
input-array="data.myInputArray">
</csv-download>
<hr />
<h2>Only Required Attribute Set</h2>
<h3>Optional Attributes Default</h3>
<csv-download
input-array="data.myInputArray">
</csv-download>
</div>
</body>
</html>
I have a file with name "file.csv", this file have data below:
ID Full name
1 Steve
2 John
3 nam
4 Hạnh
5 Thủy
I use segment code below to parse this file to json file. But my results is not utf8
Code:
var fastCsv = require("fast-csv");
var fs = require("fs");
var iconv = require('iconv-lite');
var fileStream = fs.createReadStream("file.csv");
fastCsv
.fromStream(fileStream, {headers : ["id", "full_name"]})
.on("data", function(data){
console.log("------------------------");
console.log("data: ", data);
})
.on("end", function(){
console.log("done");
});
Results:
data: { id: '��I\u0000D\u0000', full_name: '\u0000F\u0000u\u0000l\u0000l\u0000 \u0000n\u0000a\u0000m\u0000e\u0000' }
data: { id: '\u00001\u0000',full_name: '\u0000S\u0000t\u0000e\u0000v\u0000e\u0000' }
data: { id: '\u00002\u0000',full_name: '\u0000J\u0000o\u0000h\u0000n\u0000' }
data: { id: '\u00003\u0000',full_name: '\u0000n\u0000a\u0000m\u0000' }
data: { id: '\u00004\u0000', full_name: '\u0000H\u0000�\u001en\u0000h\u0000' }
data: { id: '\u00005\u0000',full_name: '\u0000T\u0000h\u0000�\u001ey\u0000' }
data: { id: '\u0000', full_name: '' }
How to convert my result to utf8?
Your input file is encoded in UTF-16LE, but it has been read as if it were UTF-8.
Try opening the file with fs.createReadStream('file.csv', {encoding: 'utf-16le'}).
Take a look at Javascript Has a Unicode Problem
In your case you need to decode the escaped unicode chars. A library included with node called punycode can handle this.
Import punycode via:
var punycode = require("punycode");
Change:
console.log("firstName: ", data);
To:
console.log("firstName: ", punycode.ucs2.decode(data));
You might have to break down the data object further to decode it's properties but I can't tell from your answer what their structure is.
I'm using a route to create a PDF using meteor-pdfkit. Here is my current code which allows me to display my Calendars ID onto the PDF.
Router.route('/calendars/:_id/getPDF', function() {
var currentCalendar = this.params._id;
var doc = new PDFDocument({size: 'A4', margin: 50});
doc.fontSize(12);
doc.text(currentCalendar, 10, 30, {align: 'center', width: 200});
this.response.writeHead(200, {
'Content-type': 'application/pdf',
'Content-Disposition': "attachment; filename=test.pdf"
});
this.response.end( doc.outputSync() );
}, {where: 'server'});
However, when I try to include other information from the Calendars collection, the data comes back as undefined or creates an error. For example, if I try to call curentCalendar.name:
Router.route('/calendars/:_id/getPDF', function() {
var currentCalendar = this.params._id;
var doc = new PDFDocument({size: 'A4', margin: 50});
doc.fontSize(12);
doc.text(currentCalendar.name, 10, 30, {align: 'center', width: 200});
this.response.writeHead(200, {
'Content-type': 'application/pdf',
'Content-Disposition': "attachment; filename=test.pdf"
});
this.response.end( doc.outputSync() );
}, {where: 'server'});
I'm assuming this is because the route doesn't have access to the information from the collection. How do I allow the route to access the information from the Calendars collection?
In your code, currentCalendar is being set to an id. I think you want to write:
var currentCalendar = Calendars.findOnw(this.params._id);
Now currentCalendar will be a document with properties, e.g. currentCalendar.name.
currentCalendar.name is undefined because you are looking for a property name on the string currentCalendar which is nothing more than the id value supplied in the URL. Therefore, all it knows is a number.
What you would have to do is create some array with information about your calendars, ie:
global.calendars = [{name: "Holidays", data: ...}, {name: "Tests", data: ...}]
Then, in your route, you can then get the information based on the index as such:
doc.text(calendars[currentCalendar].name, 10, 30, {align: 'center', width: 200});
Because now calendars[currentCalendar].name is defined