I am trying to export and download a JSON object to CSV file and I have problem with Greek characters. My code works; it is not perfect, but it works.
我试图导出并下载JSON对象到CSV文件,我有希腊字符的问题。我的代码有效;它并不完美,但它确实有效。
The problem is that Greek characters looks like junk.
问题是希腊字符看起来像垃圾。
Here is my existing code:
这是我现有的代码:
function downloadJsonToCsv(jsonObject) {
var array = typeof jsonObject != "object" ? JSON.parse(jsonObject) : jsonObject;
if (array == null) {
return; // No data found on the jsonObject
}
var str = "";
for (var i = 0; i < array.length; i++) {
var line = "";
for (var index in array[i]) {
line += array[i][index] + ";"; // Set delimiter
}
// Here is an example where you would wrap the values in double quotes
// for (var index in array[i]) {
// line += '"' + array[i][index] + '",';
// }
line.slice(0,line.Length-1);
str += line + "\r\n";
}
window.open("data:text/csv;charset=utf-8," + encodeURI(str));
}
I have two questions.
我有两个问题。
- How can export this CSV file with correct Greek chars?
- 如何使用正确的希腊语字符导出此CSV文件?
- How can I export this data in Excel format and not in CSV format?
- 如何以Excel格式而不是CSV格式导出此数据?
2 个解决方案
#1
31
Export to CSV
导出为CSV
Exporting to CSV with non-ASCII characters requires prepending the file with the Byte Order Mark aka BOM. In your code change
导出为具有非ASCII字符的CSV需要在文件前加上字节顺序标记,即物料清单。在你的代码更改
var str = "";
var str =“”;
to:
至:
var str = "\uFEFF";
var str =“\ uFEFF”;
You need a modern version of Excel to recognize the BOM. As mentioned in this helpful * article, Excel 2003 and earlier will not honor the BOM correctly. I only have access to Excel 2003 on Windows, so I cannot test this at the moment, but it's fairly well documented.
您需要一个现代版本的Excel来识别BOM。正如这篇有用的*文章所述,Excel 2003及更早版本不会正确地遵守BOM。我只能在Windows*问Excel 2003,所以我暂时无法对此进行测试,但它的记录相当完整。
Sadly, Excel 2011 for the Macintosh is NOT a "modern Excel" in this sense. Happily, Google Sheets do the right thing.
遗憾的是,Excel 2011 for the Macintosh在这个意义上并不是一个“现代Excel”。令人高兴的是,Google表格做了正确的事情。
Export directly to Excel
直接导出到Excel
Here's a jsFiddle implementation of the code below. It generates a SpreadsheetXml document. The upside to this method is you could get VERY tricky ... adding in formulas and doing a lot more things specific to Excel.
这是下面代码的jsFiddle实现。它生成一个SpreadsheetXml文档。这种方法的好处是你可能会非常棘手...添加公式并做更多特定于Excel的事情。
// Test script to generate a file from JavaScript such
// that MS Excel will honor non-ASCII characters.
testJson = [
{
"name": "Tony Peña",
"city": "New York",
"country": "United States",
"birthdate": "1978-03-15",
"amount": 42
},
{
"name": "Ζαλώνης Thessaloniki",
"city": "Athens",
"country": "Greece",
"birthdate": "1987-11-23",
"amount": 42
}
];
// Simple type mapping; dates can be hard
// and I would prefer to simply use `datevalue`
// ... you could even add the formula in here.
testTypes = {
"name": "String",
"city": "String",
"country": "String",
"birthdate": "String",
"amount": "Number"
};
emitXmlHeader = function () {
var headerRow = '<ss:Row>\n';
for (var colName in testTypes) {
headerRow += ' <ss:Cell>\n';
headerRow += ' <ss:Data ss:Type="String">';
headerRow += colName + '</ss:Data>\n';
headerRow += ' </ss:Cell>\n';
}
headerRow += '</ss:Row>\n';
return '<?xml version="1.0"?>\n' +
'<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">\n' +
'<ss:Worksheet ss:Name="Sheet1">\n' +
'<ss:Table>\n\n' + headerRow;
};
emitXmlFooter = function() {
return '\n</ss:Table>\n' +
'</ss:Worksheet>\n' +
'</ss:Workbook>\n';
};
jsonToSsXml = function (jsonObject) {
var row;
var col;
var xml;
var data = typeof jsonObject != "object"
? JSON.parse(jsonObject)
: jsonObject;
xml = emitXmlHeader();
for (row = 0; row < data.length; row++) {
xml += '<ss:Row>\n';
for (col in data[row]) {
xml += ' <ss:Cell>\n';
xml += ' <ss:Data ss:Type="' + testTypes[col] + '">';
xml += data[row][col] + '</ss:Data>\n';
xml += ' </ss:Cell>\n';
}
xml += '</ss:Row>\n';
}
xml += emitXmlFooter();
return xml;
};
console.log(jsonToSsXml(testJson));
This generates the XML document below. If this XML is saved in a file named test.xls, Excel should recognize this and open it with the proper encoding.
这将生成以下XML文档。如果此XML保存在名为test.xls的文件中,则Excel应识别此项并使用正确的编码将其打开。
<?xml version="1.0"?>
<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<ss:Worksheet ss:Name="Sheet1">
<ss:Table>
<ss:Row>
<ss:Cell>
<ss:Data ss:Type="String">name</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">city</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">country</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">birthdate</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">amount</ss:Data>
</ss:Cell>
</ss:Row>
<ss:Row>
<ss:Cell>
<ss:Data ss:Type="String">Tony Peña</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">New York</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">United States</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">1978-03-15</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="Number">42</ss:Data>
</ss:Cell>
</ss:Row>
<ss:Row>
<ss:Cell>
<ss:Data ss:Type="String">Ζαλώνης Thessaloniki</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">Athens</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">Greece</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">1987-11-23</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="Number">42</ss:Data>
</ss:Cell>
</ss:Row>
</ss:Table>
</ss:Worksheet>
</ss:Workbook>
I must admit, however, my strong inclination would be to do this server-side if possible. I've used the Python library openpyxl
to do this in the past and it is fairly simple. Most server-side languages have a library that generates Excel files and they should provide much better constructs than string concatenation.
但是,我必须承认,如果可能的话,我强烈倾向于做这个服务器端。我过去曾使用Python库openpyxl来做这件事,而且非常简单。大多数服务器端语言都有一个生成Excel文件的库,它们应该提供比字符串连接更好的结构。
Anyway, see this MSDN blog for the basics. And this * article for some pros/cons of various other options.
无论如何,请参阅此MSDN博客了解基础知识。这篇*文章提供了各种其他选项的优缺点。
#2
5
To make excel read a Unicode CSV file you have to add a Byte Order Mark as the very first string in the csv. This can be accomplished via JavaScript through adding the following line in your code:
要使Excel读取Unicode CSV文件,您必须添加字节顺序标记作为csv中的第一个字符串。这可以通过JavaScript在代码中添加以下行来完成:
line="\ufeff"+line
#1
31
Export to CSV
导出为CSV
Exporting to CSV with non-ASCII characters requires prepending the file with the Byte Order Mark aka BOM. In your code change
导出为具有非ASCII字符的CSV需要在文件前加上字节顺序标记,即物料清单。在你的代码更改
var str = "";
var str =“”;
to:
至:
var str = "\uFEFF";
var str =“\ uFEFF”;
You need a modern version of Excel to recognize the BOM. As mentioned in this helpful * article, Excel 2003 and earlier will not honor the BOM correctly. I only have access to Excel 2003 on Windows, so I cannot test this at the moment, but it's fairly well documented.
您需要一个现代版本的Excel来识别BOM。正如这篇有用的*文章所述,Excel 2003及更早版本不会正确地遵守BOM。我只能在Windows*问Excel 2003,所以我暂时无法对此进行测试,但它的记录相当完整。
Sadly, Excel 2011 for the Macintosh is NOT a "modern Excel" in this sense. Happily, Google Sheets do the right thing.
遗憾的是,Excel 2011 for the Macintosh在这个意义上并不是一个“现代Excel”。令人高兴的是,Google表格做了正确的事情。
Export directly to Excel
直接导出到Excel
Here's a jsFiddle implementation of the code below. It generates a SpreadsheetXml document. The upside to this method is you could get VERY tricky ... adding in formulas and doing a lot more things specific to Excel.
这是下面代码的jsFiddle实现。它生成一个SpreadsheetXml文档。这种方法的好处是你可能会非常棘手...添加公式并做更多特定于Excel的事情。
// Test script to generate a file from JavaScript such
// that MS Excel will honor non-ASCII characters.
testJson = [
{
"name": "Tony Peña",
"city": "New York",
"country": "United States",
"birthdate": "1978-03-15",
"amount": 42
},
{
"name": "Ζαλώνης Thessaloniki",
"city": "Athens",
"country": "Greece",
"birthdate": "1987-11-23",
"amount": 42
}
];
// Simple type mapping; dates can be hard
// and I would prefer to simply use `datevalue`
// ... you could even add the formula in here.
testTypes = {
"name": "String",
"city": "String",
"country": "String",
"birthdate": "String",
"amount": "Number"
};
emitXmlHeader = function () {
var headerRow = '<ss:Row>\n';
for (var colName in testTypes) {
headerRow += ' <ss:Cell>\n';
headerRow += ' <ss:Data ss:Type="String">';
headerRow += colName + '</ss:Data>\n';
headerRow += ' </ss:Cell>\n';
}
headerRow += '</ss:Row>\n';
return '<?xml version="1.0"?>\n' +
'<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">\n' +
'<ss:Worksheet ss:Name="Sheet1">\n' +
'<ss:Table>\n\n' + headerRow;
};
emitXmlFooter = function() {
return '\n</ss:Table>\n' +
'</ss:Worksheet>\n' +
'</ss:Workbook>\n';
};
jsonToSsXml = function (jsonObject) {
var row;
var col;
var xml;
var data = typeof jsonObject != "object"
? JSON.parse(jsonObject)
: jsonObject;
xml = emitXmlHeader();
for (row = 0; row < data.length; row++) {
xml += '<ss:Row>\n';
for (col in data[row]) {
xml += ' <ss:Cell>\n';
xml += ' <ss:Data ss:Type="' + testTypes[col] + '">';
xml += data[row][col] + '</ss:Data>\n';
xml += ' </ss:Cell>\n';
}
xml += '</ss:Row>\n';
}
xml += emitXmlFooter();
return xml;
};
console.log(jsonToSsXml(testJson));
This generates the XML document below. If this XML is saved in a file named test.xls, Excel should recognize this and open it with the proper encoding.
这将生成以下XML文档。如果此XML保存在名为test.xls的文件中,则Excel应识别此项并使用正确的编码将其打开。
<?xml version="1.0"?>
<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<ss:Worksheet ss:Name="Sheet1">
<ss:Table>
<ss:Row>
<ss:Cell>
<ss:Data ss:Type="String">name</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">city</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">country</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">birthdate</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">amount</ss:Data>
</ss:Cell>
</ss:Row>
<ss:Row>
<ss:Cell>
<ss:Data ss:Type="String">Tony Peña</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">New York</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">United States</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">1978-03-15</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="Number">42</ss:Data>
</ss:Cell>
</ss:Row>
<ss:Row>
<ss:Cell>
<ss:Data ss:Type="String">Ζαλώνης Thessaloniki</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">Athens</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">Greece</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="String">1987-11-23</ss:Data>
</ss:Cell>
<ss:Cell>
<ss:Data ss:Type="Number">42</ss:Data>
</ss:Cell>
</ss:Row>
</ss:Table>
</ss:Worksheet>
</ss:Workbook>
I must admit, however, my strong inclination would be to do this server-side if possible. I've used the Python library openpyxl
to do this in the past and it is fairly simple. Most server-side languages have a library that generates Excel files and they should provide much better constructs than string concatenation.
但是,我必须承认,如果可能的话,我强烈倾向于做这个服务器端。我过去曾使用Python库openpyxl来做这件事,而且非常简单。大多数服务器端语言都有一个生成Excel文件的库,它们应该提供比字符串连接更好的结构。
Anyway, see this MSDN blog for the basics. And this * article for some pros/cons of various other options.
无论如何,请参阅此MSDN博客了解基础知识。这篇*文章提供了各种其他选项的优缺点。
#2
5
To make excel read a Unicode CSV file you have to add a Byte Order Mark as the very first string in the csv. This can be accomplished via JavaScript through adding the following line in your code:
要使Excel读取Unicode CSV文件,您必须添加字节顺序标记作为csv中的第一个字符串。这可以通过JavaScript在代码中添加以下行来完成:
line="\ufeff"+line