js使用exceljs组件读excel文件单元格的实际值而非显示值
最近要写一个页面,上传 excel 文档,读一些固定栏位存入 DB,并做一些简单的计算,计算均值、标准差等。原本很简单的需求,计算的结果却和 excel 中公式计算结果对不上,并且相差不少,绝不是简单的 2.0 变成 2.0000000001 的问题。仔细检查发现原来 excel 中有些单元格中是小数点后4位小数,结果显示为3位小数,最终导致计算结果的差异。
因此最终的需求就变成读取文档的数字的存储数值,而非显示显示数值。
有下面一个的简单测试表格,A-J列为3位或者4位小数,N列为公式计算结果。

首先测试了xlsx.js这个组件,看是否满足需求
xlsx.js
<script src="./plugins/jquery/jquery-1.12.4.min.js"></script>
<script src="./plugins/xlsx.full.min.js"></script>
<input type="file" id="uploadFile" accept=".xls,.xlsx,.xlsm" />
<button onclick="uploadExcel(this)">uploadExcel</button>
<script>
function uploadExcel(elem) {
const file = $("#uploadFile")[0].files[0];
const fileTypes = [
"application/vnd.ms-excel", //xls
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", //xlsx
"application/vnd.ms-excel.sheet.macroEnabled.12", //xlsm
];
if (!file || file.size < 1 || fileTypes.indexOf(file.type) === -1) {
alert("請選擇EXCEL文檔");
return;
}
const reader = new FileReader();
const data = [];
reader.onload = function (e) {
const workbook = XLSX.read(e.target.result, {
type: "binary",
cellDates: true,
});
const sheetNames = workbook.SheetNames;
const worksheet = workbook.Sheets[sheetNames[0]];
const csv_data = XLSX.utils.sheet_to_csv(worksheet).split("\n");
console.log(sheetNames);
for (let row of csv_data) {
console.log(row);
}
};
reader.readAsBinaryString(file);
}
</script>
结果,读取的数值为文档的显示数字,而非实际数字。
<
PhpSpreadsheet
require '../libs/phpoffice/vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
ini_set("memory_limit", -1);
ini_set('max_execution_time', 0);
#读文件
$file_name = '../files/Book1.xlsx';
$spreadSheet = IOFactory::load($file_name); //载入xlsx文件
$sheet = $spreadSheet->getSheetByName('Sheet1'); //根据表名获取工作表
//最大行数
$row_num = $sheet->getHighestRow();
//最大列数
$col_num = $sheet->getHighestColumn();
//获取当前工作表所有有数据
$data = $sheet->toArray(); //二位数组
echo '<pre>';
var_dump($row_num, $col_num);
var_dump($data);
结果,读取的数值为文档的显示数字,而非实际数字

exceljs
<script src="./plugins/jquery/jquery-1.12.4.min.js"></script>
<script src="./plugins/exceljs/exceljs.js"></script>
<input type="file" id="uploadFile" accept=".xls,.xlsx,.xlsm" />
<button onclick="uploadExcel(this)">uploadExcel</button>
<script>
function uploadExcel(elem) {
const file = $("#uploadFile")[0].files[0];
const fileTypes = [
"application/vnd.ms-excel", //xls
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", //xlsx
"application/vnd.ms-excel.sheet.macroEnabled.12", //xlsm
];
if (!file || file.size < 1 || fileTypes.indexOf(file.type) === -1) {
alert("請選擇EXCEL文檔");
return;
}
const reader = new FileReader();
reader.onload = function (e) {
const workbook = new ExcelJS.Workbook();
const data_res = {};
let rowCount, row, rows;
workbook.xlsx
.load(e.target.result, {
ignoreNodes: ["autoFilter", "headerFooter", "hyperlinks", "pageMargins", "dataValidations", "mergeCells", "printOptions", "picture", "drawing", "conditionalFormatting"],
})
.then((res) => {
for (let worksheet of workbook.worksheets) {
console.log(worksheet.name);
row = worksheet.getRow(1);
console.log(row.values);
rowCount = worksheet.rowCount;
console.log(rowCount);
rows = worksheet.getRows(2, rowCount - 1);
for (row of rows) {
console.log(row.values);
}
}
//遍历每张工作表
// workbook.eachSheet(function (worksheet, sheetId) {
// //遍历每行
// worksheet.eachRow({ includeEmpty: true }, function (row, rowNumber) {
// console.log(row, rowNumber);
// });
// });
});
};
reader.readAsBinaryString(file);
}
function getDate(str) {
const date = new Date(str);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${date.getDate()}`;
}
</script>
结果:读取的数值为文档的实际存储数值。并且各单元格依照存储的格式解析为对应的值,公式单元格中包括公式和结果。

exceljs 可以满足需求。
浙公网安备 33010602011771号