iT邦幫忙

0

如何透過javaScript將下載內容的格式設定為 Windows (CRLF) ANSI 編碼,並且中文字內容沒有亂碼呢?

  • 分享至 

  • xImage

這是我目前研究這一部分的程式碼,還請各位IT先進、大佬們教導我!
解析日期及創建文件名稱的部分暫時和這次詢問的內容無關~

textContent的內容大致為這個樣子的資料
(包含了一些資訊,例如身分證、姓名、地址等等,有些部分省略沒有貼在這邊)

// 將資料組合成一行文本 (按照範例文件的格式)
const rowText = `${id_no},${birth_date},${pt_name},${tel_home},${tel_mobile},
${area_code},${address},,${''.repeat(20)},${formatted_penicillinrsi},${formatted_ampicillinrsi},${formatted_clindamycinrsi},${formatted_erythromycinrsi},${formatted_vancomycinrsi}\n`;

// 將每一行的文本加入到總文本中
textContent += rowText;	
// 創建一個 Blob 並下載
			const encoder = new TextEncoder();
			const encodedContent = encoder.encode(textContent);
			const blob = new Blob([encodedContent], { type: 'text/plain;charset=windows-1252' });

			// 將 Blob 轉換成 ArrayBuffer
			const reader = new FileReader();
			reader.onload = function() {
				const text = reader.result;

				// 將 LF 換行符替換為 CRLF
				const content = text.replace(/\n/g, '\r\n');

				// 將文本內容轉換為 ArrayBuffer
				const buffer = new ArrayBuffer(content.length);
				const view = new Uint8Array(buffer);
				for (let i = 0; i < content.length; i++) {
					view[i] = content.charCodeAt(i);
				}

				// 創建 Blob 對象
				const blob = new Blob([view], { type: 'text/plain;charset=windows-1252' });

				// 創建下載連結
				const url = window.URL.createObjectURL(blob);
				const a = document.createElement('a');
				a.style.display = 'none';
				a.href = url;

				// 解析日期時間
				const [datePart, timePart] = ftp_date_time.split(':');
				const [month, day] = datePart.split('-');
				const hour = timePart;
				const minute = ftp_date_time.split(':')[2]; // 拿到分鐘部分

				// 創建文件名
				const fileName = `gbs${month}${day}_${hour}${minute}.txt`;

				a.download = fileName;
				document.body.appendChild(a);
				a.click();

				window.URL.revokeObjectURL(url);
				document.body.removeChild(a);
			};
			reader.readAsText(blob);

目前的需求主要是希望最後要下載出 Windows (CRLF) ANSI 編碼格式的.txt檔,先前前一個系統輸出的編碼就是這樣,可以的話我在想是否能一樣用同樣的編碼,因為這一個.txt檔案最後會上傳至政府單位,除了檔案內容的格式之外,我也想把編碼的部分調整一樣的...
以免編碼錯誤,先前用UTF-8編碼後就失敗,雖然當中文字檔案的格式有一些部分我似乎沒調整好...
但是 UTF-8 編碼上傳後,從那個網站下載出錯誤的檔案時,我的文字檔案中「中文」的部份就會是亂碼,像是姓名、地址的部分

先前是顧慮到編碼如果不是 ANSI 的話,由於舊系統的文字檔案就是 ANSI 編碼,上傳至政府單位這一個部分可能會出問題,但是現在測試之後似乎沒有這個問題,因此這個問題也就意外地不見了

看更多先前的討論...收起先前的討論...
淺水員 iT邦大師 6 級 ‧ 2024-06-01 09:51:20 檢舉
TextEncoder 只會用 utf8 編碼
必須用其他方式編碼
請問是否有其他可以符合這個需求的編碼方式呢?
淺水員 iT邦大師 6 級 ‧ 2024-06-01 10:11:41 檢舉
內建的我不知道
有可能要找其他 library 或是下載 unicode -> cp950 的表格自己處理
好的,謝謝您!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
純真的人
iT邦大師 1 級 ‧ 2024-06-01 10:31:37

謝謝您的分享!
目前的需求主要是最後要下載出 Windows (CRLF) ANSI 編碼 格式的.txt檔,先前前一個系統輸出的編碼就是這樣,可以的話我在想是否能一樣用同樣的編碼,因為這一個.txt檔案最後會上傳至政府單位,除了檔案內容的格式之外,我也想把編碼的部分調整一樣的...

0
淺水員
iT邦大師 6 級 ‧ 2024-06-01 10:32:43

稍微整理一下

  • TextEncoder 只會以 utf8 編碼,這要另外找 library 處理
  • 「換行符替換為 CRLF」直接在原始字串處理就好,不需要用 FileReader 解碼再處理
/**
 * 將字串編碼為 cp950
 * @param {string} str 字串
 * @returns {Uint8Array}
 */
function encodeCP950(str) {
    // TextEncoder 只會以 utf8 編碼
    // 可能要找其他函式庫
    const encoder = new TextEncoder();
    return encoder.encode(str);
}

// 將 LF 換行符替換為 CRLF
let content = textContent.replace(/\n/g, '\r\n');

// 轉成 cp950
content = encodeCP950(content);

// 產生 url
let blob = new Blob([content], {type: 'text/plain'});
const url = window.URL.createObjectURL(blob);

// 產生下載程式碼(略)

window.URL.revokeObjectURL(url);

好的,感謝您特地整理內容!

不明
【**此則訊息已被站方移除**】

我要發表回答

立即登入回答