el-table样式

导出的excel样式

实现代码
import { utils } from 'xlsx';
import * as XLSX_STYLE from 'xlsx-style-vite';
import FileSaver from 'file-saver';
function getStringWidth(text, fontSize) {
const span = document.createElement('span');
span.style.font = 'bold';
if (fontSize) {
span.style.fontSize = fontSize + 'px';
}
span.style.visibility = 'hidden';
span.style.whiteSpace = 'pre';
span.innerText = text;
document.body.appendChild(span);
const width = span.offsetWidth;
document.body.removeChild(span);
return width;
}
export function exportByElTable(elTableRef, option) {
if (!elTableRef) return;
const { filename, badDataLocation = {}, headRowSpan = 1, isTopHead = false, boldFirstCol = false } = option;
const { $el } = elTableRef;
const wb = utils.book_new();
const headerDOM = $el.querySelector('.el-table .el-table__header-wrapper .el-table__header');
const bodyDOM = $el.querySelector('.el-table .el-table__body-wrapper .el-table__body');
let element = document.createElement('div');
if (headerDOM) {
element.appendChild(headerDOM.cloneNode(true));
}
element.appendChild(bodyDOM.cloneNode(true));
const sheet = utils.table_to_sheet(element, { raw: true });
const colWidths = [];
const range = utils.decode_range(sheet['!ref']);
const borderStyle = { style: 'thin', color: { rgb: '000000' } };
const getBorderStyleObj = (direction, cell) => {
const obj = cell || { s: { border: {} } };
obj.s.border[direction] = borderStyle;
return obj;
};
for (let C = range.s.c; C <= range.e.c; ++C) {
let maxWidth = 60;
for (let R = range.s.r; R <= range.e.r; ++R) {
const cellRef = utils.encode_cell({ r: R, c: C });
const cell = sheet[cellRef];
if (!cell?.t) {
if (isTopHead && R == 0 && C > 0) {
sheet[cellRef] = getBorderStyleObj('bottom', sheet[cellRef]);
}
if (R == range.e.r) {
sheet[cellRef] = getBorderStyleObj('bottom', sheet[cellRef]);
} else if (R > 0) {
const topCellRef = utils.encode_cell({ r: R - 1, c: C });
const topCell = sheet[topCellRef];
const bottomCellRef = utils.encode_cell({ r: R + 1, c: C });
const bottomCell = sheet[bottomCellRef];
if (!topCell?.t && bottomCell?.t) {
sheet[cellRef] = getBorderStyleObj('top', sheet[cellRef]);
}
}
if (C == range.e.c) {
sheet[cellRef] = getBorderStyleObj('right', sheet[cellRef]);
} else if (C > 0) {
const leftCellRef = utils.encode_cell({ r: R, c: C - 1 });
const leftCell = sheet[leftCellRef];
const rightCellRef = utils.encode_cell({ r: R, c: C + 1 });
const rightCell = sheet[rightCellRef];
if (!leftCell?.t && rightCell?.t) {
sheet[cellRef] = getBorderStyleObj('left', sheet[cellRef]);
}
}
continue;
}
const cellStyle = {
border: {
top: borderStyle,
bottom: borderStyle,
left: borderStyle,
right: borderStyle,
},
alignment: { horizontal: 'center', vertical: 'center' },
};
if (C == 0 && boldFirstCol) {
cellStyle.font = { bold: true };
}
if (R < headRowSpan) {
cellStyle.font = { bold: true };
}
if (isTopHead && R == 0) {
cellStyle.font = { bold: true, sz: 18 };
}
if (badDataLocation[R] && badDataLocation[R].includes(C)) {
cellStyle.font = { color: { rgb: 'FF0000' } };
}
cell.s = cellStyle;
if (cell.v) {
if (isTopHead && R == 0) {
continue;
}
const cellValue = cell.v.toString();
let fontSize = C == range.e.c ? 16 : 14;
maxWidth = Math.max(maxWidth, getStringWidth(cellValue, fontSize));
}
}
colWidths.push({ wpx: maxWidth });
}
sheet['!cols'] = colWidths;
utils.book_append_sheet(wb, sheet);
element = null;
const s2ab = (s) => {
const buf = new ArrayBuffer(s.length);
const view = new Uint8Array(buf);
for (let i = 0; i < s.length; i++) {
view[i] = s.charCodeAt(i) & 0xff;
}
return buf;
};
const writeOption = {
bookType: 'xlsx',
bookSST: false,
type: 'binary',
cellStyles: true,
};
const wbout = XLSX_STYLE.write(wb, writeOption);
try {
FileSaver.saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream;charset=utf-8"' }), filename);
} catch (e) {
if (typeof console !== 'undefined') {
}
}
}