我有这个有人手动创建的 excel 文件,我需要尝试以编程方式重新创建它。
我有一个将数据导出到 csv 文件的 node.js(TS) 服务。 显然我不能生成看起来像这样的 csv 文件。 我需要稍微改变逻辑并尝试生成尽可能接近此文件的 xlsx 文件:
我环顾四周,找不到任何有用的东西。 不要介意颜色,我对第 1 行和第 2 行更感兴趣。
谢谢!
我尝试了 XSLX 包 (https://www.npmjs.com/package/xlsx) 但甚至没有接近预期的结果。
exceljs
库
演示 我使用这个 excel 文件。
代码
const ExcelJS = require('exceljs');
const fs = require('fs');
const wb = new ExcelJS.Workbook();
// input excel file name
const fileName = 'bar-code-data.xlsx';
const csv_fileName = 'result.csv';
// convert index to column name
const columnName = (index) => {
var cname = String.fromCharCode(65 + ((index - 1) % 26))
if (index > 26)
cname = String.fromCharCode(64 + (index - 1) / 26) + cname
return cname;
}
// apped row into CSV
const appendToCSV = (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16) => {
const csv = `${c1},${c2},${c3},${c4},${c5},${c6},${c7},${c8},${c9},${c10},${c11},${c12},${c13},${c14},${c15},${c16}\n`;
try {
fs.appendFileSync(csv_fileName, csv);
} catch (err) {
console.error(err);
}
}
wb.xlsx.readFile(fileName).then(() => {
const ws = wb.getWorksheet('Sheet1');
// get merged cells title
const a1_title = ws.getCell('A1').value
const d1_title = ws.getCell('D1').value
const h1_title = ws.getCell('H1').value
const m1_title = ws.getCell('M1').value
// set row loop count variables
const headerColumn = 1
const start_row = 3
const how_many_rows = 2
// reading excel cell data
for (let row_number = start_row; row_number < start_row + how_many_rows; row_number++) {
if (row_number == start_row) {
// reading sub titles
const a1_sub_title1 = a1_title + ' ' + ws.getCell(columnName(headerColumn) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const a1_sub_title2 = a1_title + ' ' + ws.getCell(columnName(headerColumn + 1) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const a1_sub_title3 = a1_title + ' ' + ws.getCell(columnName(headerColumn + 2) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const a1_sub_title4 = a1_title + ' ' + ws.getCell(columnName(headerColumn + 3) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const d1_sub_title1 = d1_title + ' ' + ws.getCell(columnName(headerColumn + 4) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const d1_sub_title2 = d1_title + ' ' + ws.getCell(columnName(headerColumn + 5) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const d1_sub_title3 = d1_title + ' ' + ws.getCell(columnName(headerColumn + 6) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const h1_sub_title1 = h1_title + ' ' + ws.getCell(columnName(headerColumn + 7) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const h1_sub_title2 = h1_title + ' ' + ws.getCell(columnName(headerColumn + 8) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const h1_sub_title3 = h1_title + ' ' + ws.getCell(columnName(headerColumn + 9) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const h1_sub_title4 = h1_title + ' ' + ws.getCell(columnName(headerColumn + 10) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const h1_sub_title5 = h1_title + ' ' + ws.getCell(columnName(headerColumn + 11) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const m1_sub_title1 = m1_title + ' ' + ws.getCell(columnName(headerColumn + 12) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const m1_sub_title2 = m1_title + ' ' + ws.getCell(columnName(headerColumn + 13) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const m1_sub_title3 = m1_title + ' ' + ws.getCell(columnName(headerColumn + 14) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
const m1_sub_title4 = m1_title + ' ' + ws.getCell(columnName(headerColumn + 15) + String(row_number - 1)).value.replace(/\r?\n|\r/g, " ")
// save header title
appendToCSV(a1_sub_title1, a1_sub_title1, a1_sub_title3, a1_sub_title4,
d1_sub_title1, d1_sub_title2, d1_sub_title3,
h1_sub_title1, h1_sub_title2, h1_sub_title3, h1_sub_title4, h1_sub_title5,
m1_sub_title1, m1_sub_title2, m1_sub_title3, m1_sub_title4)
}
const barcode = ws.getCell(columnName(headerColumn) + String(row_number)).value
const ppid = ws.getCell(columnName(headerColumn + 1) + String(row_number)).value
const site = ws.getCell(columnName(headerColumn + 2) + String(row_number)).value
const s1_tube_type = ws.getCell(columnName(headerColumn + 3) + String(row_number)).value
const s1_within_window = ws.getCell(columnName(headerColumn + 4) + String(row_number)).value
const s1_initial_quantity = ws.getCell(columnName(headerColumn + 5) + String(row_number)).value
const s1_temperature_deviation = ws.getCell(columnName(headerColumn + 6) + String(row_number)).value
const sp1_tube_type = ws.getCell(columnName(headerColumn + 7) + String(row_number)).value
const sp1_initial_quantity = ws.getCell(columnName(headerColumn + 8) + String(row_number)).value
const sp1_qc_status = ws.getCell(columnName(headerColumn + 9) + String(row_number)).value
const sp1_pre_qc_check1 = ws.getCell(columnName(headerColumn + 10) + String(row_number)).value
const sp1_pre_qc_check2 = ws.getCell(columnName(headerColumn + 11) + String(row_number)).value
const s2_tube_type = ws.getCell(columnName(headerColumn + 12) + String(row_number)).value
const s2_within_window = ws.getCell(columnName(headerColumn + 13) + String(row_number)).value
const s2_initial_quantity = ws.getCell(columnName(headerColumn + 14) + String(row_number)).value
const s2_temperature_deviation = ws.getCell(columnName(headerColumn + 15) + String(row_number)).value
// save data row
appendToCSV((barcode === null)? '' : barcode,
(ppid === null)? '' : ppid,
(site === null)? '' : site,
(s1_tube_type === null)? '' : s1_tube_type,
(s1_within_window === null)? '' : s1_within_window,
(s1_initial_quantity === null)? '' : s1_initial_quantity,
(s1_temperature_deviation === null)? '' : s1_temperature_deviation,
(sp1_tube_type === null)? '' : sp1_tube_type,
(sp1_initial_quantity === null)? '' : sp1_initial_quantity,
(sp1_qc_status === null)? '' : sp1_qc_status,
(sp1_pre_qc_check1 === null)? '' : sp1_pre_qc_check1,
(sp1_pre_qc_check2 === null)? '' : sp1_pre_qc_check2,
(s2_tube_type === null)? '' : s2_tube_type,
(s2_within_window === null)? '' : s2_within_window,
(s2_initial_quantity === null)? '' : s2_initial_quantity,
(s2_temperature_deviation === null)? '' : s2_temperature_deviation)
}
}).catch(err => {
console.log(err.message);
});
贴士
#1 此代码将多行标题替换为单行标题
replace(/\r?\n|\r/g, " ")
#2
columnName
功能:按数字转换列名
columnName(1) -> A
columnName(2) -> B
#3 空检查 如果值为空,则替换空白字符
(value === null)? '' : value
#4 追加行
csv
字符串将附加到 CSV 文件中
fs.appendFileSync(csv_fileName, csv);