文章目錄
- 1. 基礎配置
- 1.1 單元格內容
- 1.2 單元格合并、列寬、行高
- 1.3 單元格樣式
- 2. sheet 配置、多個 sheet
- 3. excel 導出
- 4. 數據插入(進階)
1. 基礎配置
1.1 單元格內容
注:xlsx、xlsx-style 都存在 write 方法,xlsx 設置單元格樣式沒有效果,xlsx-style 設置行高沒有效果
// 首選需要安裝 npm i xlsx xlsx-style
imoprt XLSX from "xlsx"let arr = [{date: "2016-05-02",name: "王小虎",address: "上海市普陀區金沙江路 1518 弄",},{date: "2016-05-04",name: "王小虎",address: "上海市普陀區金沙江路 1517 弄",}
];// 處理成 XLSX 認識的格式
XLSX.utils.json_to_sheet(arr);
/** 可以看到自動把 key 變為第一行的標題了,value 依此排列* { // 這里的對象也可以手動自行配置* "!ref": "A1:C3", // 表示表格內容范圍A1: { t: "s", v: "date" }, // t: 格式 v: 內容A2: { t: "s", v: "2016-05-02" },A3: { t: "s", v: "2016-05-04" },B1: { t: "s", v: "name" },B2: { t: "s", v: "王小虎" },B3: { t: "s", v: "王小虎" },C1: { t: "s", v: "address" },C2: { t: "s", v: "上海市普陀區金沙江路 1518 弄" },C3: { t: "s", v: "上海市普陀區金沙江路 1517 弄" }}*/
1.2 單元格合并、列寬、行高
let worksheet = {"!cols": [{ wpx: 140 }, { wpx: 80 }],"!rows": [{ hpx: 14 }, { hpx: 14 }],"!ref": "A1:C3","!merges": [{ s: { r: 0, c: 0 }, e: { r: 0, c: 2 } }] // 合并第一行的 1~3 列
}
1.3 單元格樣式
let cell = {t: "s",v: "測試",s: {alignment: {vertical: "center", // 垂直居中horizontal: "center", // 水平居中wrapText: "true", // 文本換行readingOrder: "2", // 閱讀順序,從右往左textRotation: "180" // 文本旋轉},border: {top: { style: "邊框樣式", color: { rgb: "邊框顏色" }}bottom: {}...},font: {name: "字體", sz: "字體大小",color: { rgb: "字體顏色" },bold: "是否加粗"},fill: {bgColor: { rgb: "背景顏色" }}}
}
2. sheet 配置、多個 sheet
import XLSX from "xlsx" // 只能使用 xlsx
const wb = XLSX.utils.book_new(); // 創建工作簿
const sheet1 = XLSX.utils.json_to_sheet(arr1)
const sheet2 = XLSX.utils.json_to_sheet(arr2)
XLSX.utils.book_append_sheet(wb1, sheet, 'sheet1名稱');
XLSX.utils.book_append_sheet(wb2, sheet, 'sheet2名稱');
// 這個時候的 wb 的數據就完整了
3. excel 導出
// 將 workbook 裝化成 blob 對象
// 這里用到了 XLSX.write,注意是使用的哪種 import XLSX from "xlsx"/"xlsx-style"
function workbook2blob(workbook) {// 生成excel的配置項var wopts = {// 要生成的文件類型bookType: "xlsx",// 是否生成Shared String Table,官方解釋是,如果開啟生成速度會下降,但在低版本IOS設備上有更好的兼容性bookSST: false,type: "binary",};var wbout = XLSX.write(workbook, wopts);// 將字符串轉 ArrayBufferfunction s2ab(s) {var buf = new ArrayBuffer(s.length);var view = new Uint8Array(buf);for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;return buf;}var blob = new Blob([s2ab(wbout)], {type: "application/octet-stream",});return blob;
}// 將 blob 對象創建 bloburl,然后用 a 標簽實現彈出下載框
function openDownloadDialog(blob, fileName) {if (typeof blob == "object" && blob instanceof Blob) {blob = URL.createObjectURL(blob); // 創建blob地址}var aLink = document.createElement("a");aLink.href = blob;// HTML5 新增的屬性,指定保存文件名,可以不要后綴,注意,有時候 file:///模式下不會生效aLink.download = fileName || "";var event;if (window.MouseEvent) event = new MouseEvent("click");// 移動端else {event = document.createEvent("MouseEvents");event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);}aLink.dispatchEvent(event);
}openDownloadDialog(workbook2blob(wb), "excel下載.xlsx");
4. 數據插入(進階)
// 數據的更新(插入行,向下平移)
// 插入指定行同理 修改循環時的初始值就好了
function insertRowsBeforeData(worksheet, rowLen = 1, callback) {// 獲取當前工作表范圍const range = worksheet["!ref"] ? XLSX.utils.decode_range(worksheet["!ref"]) : null;// 計算要插入的行數const insertRows = rowLen;// 處理合并單元格 - 下移現有合并區域if (worksheet["!merges"]) {worksheet["!merges"] = worksheet["!merges"].map((merge) => {const newMerge = { ...merge };// 移動合并區域的起始行和結束行newMerge.s.r += insertRows;newMerge.e.r += insertRows;return newMerge;});}// 處理數據,下移現有數據if (range) {// 從最后一行開始向上移動,避免覆蓋for (let row = range.e.r; row >= range.s.r; row--) {for (let col = range.s.c; col <= range.e.c; col++) {const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });if (worksheet[cellAddress]) {// 計算新位置(向下移動insertRows行)const newRow = row + insertRows;const newAddress = XLSX.utils.encode_cell({ r: newRow, c: col });// 移動單元格worksheet[newAddress] = worksheet[cellAddress];// 刪除原始位置的單元格delete worksheet[cellAddress];}}}// 更新工作表范圍range.e.r += insertRows;worksheet["!ref"] = XLSX.utils.encode_range(range);}// 插入數據callback && callback();
}this.insertRowsBeforeData(worksheet, 1, () => {worksheet.A1 = { t: "s", v: "我是新插入的數據1" }worksheet.B1 = { t: "s", v: "我是新插入的數據2" }
});