Javascript -> 下载以 ISO-8859-1 / Latin1 / Windows-1252 编码的 CSV 文件
Posted
技术标签:
【中文标题】Javascript -> 下载以 ISO-8859-1 / Latin1 / Windows-1252 编码的 CSV 文件【英文标题】:Javascript -> Download CSV file encoded in ISO-8859-1 / Latin1 / Windows-1252 【发布时间】:2015-10-17 17:01:37 【问题描述】:我已经编写了一个小工具来从 Amazon CSV 订单数据中提取运输数据。到目前为止它有效。这里是一个简单的版本,如 JS Bin:http://output.jsbin.com/jarako
为了打印邮票/运输标签,我需要一个文件来上传到德国邮政和其他包裹服务。我使用了一个小函数saveTextAsFile
,它是在*** 上找到的。到目前为止一切都很好。输出文本区域或下载的文件中没有错误显示的特殊字符 (äöüß...)。
所有这些德国邮政/包裹服务网站仅接受 latin1 / iso-8859-1 编码文件进行上传。但我下载的文件始终是 utf-8。如果我上传它,所有特殊字符(äöüß...)都会出错。
我该如何改变呢?我还是找了很多。我试过了,即:
将工具的字符集设置为 iso-8859-1:
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
但结果是:现在我在输出文本区域和下载的文件中仍有错误的特殊字符。如果我将它上传到帖子网站,我仍然会得到更多错误的字符。此外,如果我在 CODA 编辑器中检查编码,它仍然说下载的文件是 UTF-8。
saveTextAsFile
函数使用var textFileAsBlob = new Blob([textToWrite], type:'text/plain');
。可能有办法设置字符集以供下载!?
function saveTextAsFile()
var textToWrite = $('#dataOutput').val();
var textFileAsBlob = new Blob([textToWrite], type:'text/plain');
var fileNameToSaveAs = "Brief.txt";
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null)
// Chrome allows the link to be clicked
// without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
else
// Firefox requires the link to be added to the DOM
// before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
downloadLink.click();
无论如何,必须有一种方法可以下载其他编码的文件,因为网站使用自己。我从中下载 CSV 文件的亚马逊网站是 UTF-8 编码的。但是如果我在 CODA 中检查它,从那里下载的 CSV 文件是 Latin1 (iso-8859-1)...
【问题讨论】:
【参考方案1】:向下滚动到更新以获得真正的解决方案!
因为我没有得到答案,所以我搜索得越来越多。看起来 javascript 中没有解决方案。我所做的每个测试下载都是用 javascript 生成的,都是 UTF-8 编码的。看起来 Javascript 仅适用于 UNICODE / UTF-8 或其他编码(可能)仅适用于使用以前的 HTTP 传输再次传输数据的情况。但是对于在客户端上运行的 Javascript,不会发生额外的 HTTP 传输,因为数据仍在客户端上..
我现在帮助我在我的服务器上构建了一个小型 php 脚本,我通过 GET 或 POST 请求将数据发送到该脚本。它将编码转换为 latin1 / ISO-8859-1 并将其作为文件下载。这是一个带有正确编码的特殊字符的 ISO-8859-1 文件,我可以将其上传到上述邮政和包裹服务站点,一切看起来都很好。
latin-download.php:(将 PHP 文件本身也保存在 ISO-8859-1 中以使其正常工作非常重要!!)
<?php
$decoded_a = urldecode($_REQUEST["a"]);
$converted_to_latin = mb_convert_encoding($decoded_a,'ISO-8859-1', 'UTF-8');
$filename = $_REQUEST["filename"];
header('Content-Disposition: attachment; filename="'.$filename.'"; content-type: text/plain; charset=iso-8859-1;');
echo $converted_to_latin;
?>
在我使用的 javascript 代码中:
<a id="downloadlink">Download File</a>
<script>
var mydata = "this is testdata containing äöüß";
document.getElementById("downloadlink").addEventListener("click", function()
var mydataToSend = encodeURIComponent(mydata);
window.open("latin-download.php?a=" + mydataToSend + "&filename=letter-max.csv");
, false);
</script>
对于更大量的数据,您必须从 GET 切换到 POST...
2016 年 2 月 8 日更新
半年后,我在 PURE JAVASCRIPT 中找到了解决方案。使用inexorabletash/text-encoding。这是Encoding Living Standard 的 polyfill。该标准包括对 latin1(“windows-1252”)等旧编码的解码,但它禁止编码为这些旧编码类型。因此,如果您使用浏览器实现的window.TextEncoder
功能,它确实只提供UTF 编码。但是,polyfill solution 提供了一种传统模式,它也允许编码成旧的编码,如 latin1。
我就是这样用的:
<!DOCTYPE html>
<script>
// 'Copy' browser build in TextEncoder function to TextEncoderOrg (because it can NOT encode windows-1252, but so you can still use it as TextEncoderOrg() )
var TextEncoderOrg = window.TextEncoder;
// ... and deactivate it, to make sure only the polyfill encoder script that follows will be used
window.TextEncoder = null;
</script>
<script src="lib/encoding-indexes.js"></script> // needed to support encode to old encoding types
<script src="lib/encoding.js"></script> // encording polyfill
<script>
function download (content, filename, contentType)
if(!contentType) contentType = 'application/octet-stream';
var a = document.createElement('a');
var blob = new Blob([content], 'type':contentType);
a.href = window.URL.createObjectURL(blob);
a.download = filename;
a.click();
var text = "Es wird ein schöner Tag!";
// Do the encoding
var encoded = new TextEncoder("windows-1252", NONSTANDARD_allowLegacyEncoding: true ).encode(text);
// Download 2 files to see the difference
download(encoded,"windows-1252-encoded-text.txt");
download(text,"utf-8-original-text.txt");
</script>
encoding-indexes.js 文件大约 500kb 大,因为它包含所有编码表。因为我只需要 windows-1252 编码,为了我的使用,我已经删除了这个文件中的其他编码。所以现在只剩下 632 字节了。
【讨论】:
【参考方案2】:您不能强制网络服务器以给定的编码向您发送数据,只能礼貌地询问。您只需转换为所需格式的方法是正确的方法。
如果您想避免使用 PHP 脚本,您可能会幸运地在创建 Blob
时将编码指定为参数:
var textFileAsBlob = new Blob(textToWrite,
type: 'text/plain;charset=ISO-8859-1',
encoding: "ISO-8859-1"
);
更多详情请见Specifying blob encoding in Google Chrome。
【讨论】:
感谢您的反馈,雅各布。我仍然用'new Blob(textToWrite,encoding:“UTF-8”,type:“text/plain;charset = UTF-8”);'和类似的东西,但在我的 chrome 中,当我检查它们时,我从 blob 下载的所有文件都是 UTF-8 编码文件。 - 所以现在看来我必须忍受通往服务器的路......【参考方案3】:问题不在于编码,而在于特殊字符在某些应用程序中显示错误,例如微软 Excel。 UTF-8 可以很好地显示所有特殊的德语字符。您可以通过在 csv 前面添加字节顺序标记 (BOM) 来解决此问题。
const BOM = "\uFEFF"
let csvData = BOM + csvData
const blob = new Blob([csvData], type: "text/csv;charset=utf-8" );
基于this github post的解决方案
【讨论】:
这可能是一个解决方案,适用于接受 UTF-8 的服务,但不适用于需要 latin1 / iso-8859-1 编码的 CSV 数据的服务。无论如何,谢谢你的帖子。但有我失败。如果要在前面添加BOM,则必须使用: let csvData = BOM + csvData以上是关于Javascript -> 下载以 ISO-8859-1 / Latin1 / Windows-1252 编码的 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何编写Powershell脚本以提取.iso文件并通过创建文件夹将其复制到文件夹中