javascript - 下载文件时设置csv编码
问题描述
我正在使用 react、Paparse和encoding-japanese
使用 Paparse,我可以上传 CSV 并从 Shift-JS 对其进行解码。但是库不支持相反的操作。
我添加了 encoding-japanese,以便将字符串转换为 SHIFT-js 并下载它。
这是我的代码:
const csv = csvParser.unparse({
"fields": ["行形式","取引番号","取引日","支払期限","顧客番号","顧客企業名","顧客電話番号","送付先郵便番号","請求書発行日","郵送","メール送付","取引金額","明細","単価","数量","金額","消費税率","税込対象額_10%","税込対象額_8%","税込対象額_経8%","税込対象額_旧8%","税込対象額_非","税込対象額_対象外"],
"data": [
["取引","transaction-20200218-094750_1","2020/02/18","2020/03/31","DP79","Sample1Corp","03-0000-0000","123-4567","2020/02/19","0","1","110","","","","","","110","","","",""]
]
});
const a = document.createElement("a");
const sjisArray = Encoding.convert(csv, 'SJIS', 'UTF8');
console.log(sjisArray)
a.href = window.URL.createObjectURL(new Blob(['\ufeff'+sjisArray], {type: "text/csv;charset=shift-js"}));
a.download = "取引サンプル.csv";
a.click();
它不会抛出任何错误,但是当我在记事本中打开它时,我的 csv 文件仍然是带有 BOM 的 UTF8 格式。
我希望将它放在 shift-js 中。
我怎样才能做到这一点?
解决方案
您的Encoding
库当前正在返回一个 DOMString,因为您传递了这样一个 DOMString 作为输入。
这意味着您的Blob
构造函数会将此 DOMString 转换为 UTF-8,这就是您将在文件中拥有的内容:Shift-JIS 编码文本的 UTF-16 表示的 UTF-8 版本。
至少可以说,这不是你想要的。
快速查看该库的文档,似乎最好的方法是将文本的 ArrayBuffer 版本传递给编码,以便它返回字节值的数组(如 Uint8Array,除了它们使用普通数组进行任何操作原因...)。
然后从该字节数组中,您将能够生成一个新的 ArrayBuffer,您将能够将其传递给您的 Blob,而无需将其转换回 UTF-8。
const csv = Papa.unparse({
"fields": ["行形式","取引番号","取引日","支払期限","顧客番号","顧客企業名","顧客電話番号","送付先郵便番号","請求書発行日","郵送","メール送付","取引金額","明細","単価","数量","金額","消費税率","税込対象額_10%","税込対象額_8%","税込対象額_経8%","税込対象額_旧8%","税込対象額_非","税込対象額_対象外"],
"data": [
["取引","transaction-20200218-094750_1","2020/02/18","2020/03/31","DP79","Sample1Corp","03-0000-0000","123-4567","2020/02/19","0","1","110","","","","","","110","","","",""]
]
});
// First convert our DOMString to an ArrayBuffer
const utf8Array = new TextEncoder().encode( csv );
// pass it to Encoding so we get back an Array of bytes
const sjisArray = Encoding.convert(utf8Array, 'SJIS', 'UTF8');
// now we can make our Blob without auto encoding
const blob = new Blob( [ new Uint8Array( sjisArray ) ] );
const a = document.createElement('a');
a.download = 'Shift-JIS.csv';
a.href = URL.createObjectURL( blob );
a.textContent = 'download';
document.body.append( a );
// just to check we encoded it correctly
readAsText( blob, 'Shift-JIS' )
.then( txt => console.log( 'read back as Shift-JIS:', txt ) );
readAsText( blob, 'utf-8' )
.then( txt => console.log( 'read back as UTF-8:', txt ) );
function readAsText( blob, encoding ) {
return new Promise( (res, rej) => {
const reader = new FileReader();
reader.onerror = rej;
reader.onload = (evt) => res( reader.result );
reader.readAsText( blob, encoding );
} );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/encoding-japanese/1.0.30/encoding.min.js"></script>
推荐阅读
- reactjs - React:通过布局组件传递道具
- mobile - 会话存储不会在移动设备上动态更改依赖框值
- sorting - 如何获得b-tree的第n个值
- c# - 快速报告导致 mvc .net 中的访问被拒绝错误
- python - 如何在 Plyer 中使用语音到文本?它不工作
- c# - 当没有数据集可用时,DataGridView 显示一个空行
- module - 为什么直接绑定 `our &foo` 不起作用,但通过动态查找间接绑定呢?
- search - 在 Yii1 中使用键搜索记录
- python - 按钮按下事件 - 事件处理和选择:IndexError:列表索引超出范围
- ios - UITableView 滑动单元格的边框