今天主题:在vue-electron里,将表格导入并向其添加内容,然后导出表格,且表格样式(一般是值宽高合并颜色等)不能改变。
技术 {#heading-1}
-
electron
-
xlsx
-
xlsx-style
-
node-xlsx
yarn add xlsx
yarn add xlsx-style
yarn add node-xlsx
xlsx-style {#heading-2}
xlsx-style 的一些源码修改是根据网上一些博主的文章来的。如下所示:
使用xlsx-style 的时候要注意,使用的是会报错误,所以,我们需要改他的源码,下面是正确的修改方式,代码如下(示例)
# 第一步 修改nod_modules 里面xlsx-style文件夹下面dist文件夹下的cpexcel.js文件
807: var cpt = cptable;
# 第二步 修改xlsx-style文件夹下面ods.js文件
10: return require('./' + 'xlsx').utils;
12: try { return require('./' + 'xlsx').utils; }
# 第三步 修改xlsx-style文件夹下面的xlsx.js文件 替换write_ws_xml_data以下方法
var DEF_PPI = 96, PPI = DEF_PPI;
function px2pt(px) { return px * 96 / PPI; }
function pt2px(pt) { return pt * PPI / 96; }
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R, C,rows = ws['!rows'];
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
if(ws[ref] === undefined) continue;
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
}
if(r.length > 0){
params = ({r:rr});
if(rows && rows[R]) {
row = rows[R];
if(row.hidden) params.hidden = 1;
height = -1;
if (row.hpx) height = px2pt(row.hpx);
else if (row.hpt) height = row.hpt;
if (height > -1) { params.ht = height; params.customHeight = 1; }
if (row.level) { params.outlineLevel = row.level; }
}
o[o.length] = (writextag('row', r.join(""), params));
}
}
if(rows) for(; R < rows.length; ++R) {
if(rows && rows[R]) {
params = ({r:R+1});
row = rows[R];
if(row.hidden) params.hidden = 1;
height = -1;
if (row.hpx) height = px2pt(row.hpx);
else if (row.hpt) height = row.hpt;
if (height > -1) { params.ht = height; params.customHeight = 1; }
if (row.level) { params.outlineLevel = row.level; }
o[o.length] = (writextag('row', "", params));
}
}
return o.join("");
}
全部代码 {#heading-3}
upload方法分析
通过pdfWord.testImage()读取到表格(node环境),然对list数据里面的表格进行内容的修改以及填充,修改内容以后就将其样式调整以及转换数据类型并下载
testImage() {
const a2 = path.join('C:\\Users\\op\\Desktop', '副本.xlsx')
const sheets = xlsx.parse(a2);
//读取xlxs的sheet1
const sheetData = sheets[0].data;
return sheets[0].data;
},
-
openDownloadDialog 下载
-
sheet2blob 将样式修改后的表格转为blob格式
-
xlsxAddStyle 修改样式
其他的属性大家可以看文档即可看明白,我只能大家说一下三个自认为比较重要的东西
1."!cols"(代码中:sheet["!cols"])= 指每列单元格一列的宽度,按先后顺序排列
2."!rows"(代码中:sheet["!rows"])= 指每行单元的一行的高度,按先后顺序排列
3."!merges"(代码中:sheet["!merges"])= 指合并;没有先后顺序。s:开始 e:结束 r:列 c:行
以上三种都是可以让用户自己控制的属性,至于其他的就需要你们根据自己的需求进行调整了
在修改样式中我们会看到element一个变量;他们可以去打印这个变量查看其中的属性;你们可以到时里面有许多样式结构,你只需要根据自己想要的去修改即可。
<template>
<div>
<el-button type="primary" @click="upload">主要按钮</el-button>
</div>
</template>
<script>
import XLSXStyle from "xlsx-style";
import * as XLSX from "xlsx";
import pdfWord from "@/utils/tool/pdf-word";
export default {
name: "duplication",
components: {},
props: {},
data() {
return {
};
},
created() {},
methods: {
upload() {
let list = pdfWord.testImage();
console.log(list);
for (let i = 0; i < list.length - 1; i++) {
// console.log('op',list[i]);
if (i == 5) {
list[i] = [3, "爱情", "xx", "ssd", "wdsda"];
}
}
const sheet = this.xlsxAddStyle(list);
this.openDownloadDialog(this.sheet2blob(sheet), `1.xlsx`);
return;
},
// 下载
openDownloadDialog(url, saveName) {
var urlA;
if (typeof url === "object" && url instanceof Blob) {
urlA = URL.createObjectURL(url); // 创建blob地址
}
const aLink = document.createElement("a");
aLink.href = urlA;
// 2.直接使用自定义文件名,设置下载文件名称
aLink.setAttribute('download', saveName )
document.body.appendChild(aLink)
// 模拟点击下载
aLink.click()
// 移除改下载标签
document.body.removeChild(aLink);
},
// 转为blob文件
sheet2blob(sheet, sheetName) {
var sheetNameS = sheetName || "sheet1";
var workbook = {
SheetNames: [sheetNameS],
Sheets: {},
};
workbook.Sheets[sheetNameS] = sheet;
// 生成excel的配置项
var wopts = {
bookType: "xlsx", // 要生成的文件类型
bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
type: "binary",
};
var wbout = XLSXStyle.write(workbook, wopts);
// XLSXStyle.write(wb, { bookType: bookType, bookSST: false, type: 'binary' });
var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
// 字符串转ArrayBuffer
function 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;
};
return blob;
},
// 修改样式
xlsxAddStyle(xlsx) {
const sheet = XLSX.utils.aoa_to_sheet(xlsx);
// 单元格外侧有框线
const borderAll = {
top: { style: "thin" },
bottom: { style: "thin" },
left: { style: "thin" },
right: { style: "thin" },
};
// 单元格外侧无框线
const noBorder = {
top: { style: "thin" },
bottom: { style: "thin" },
left: { style: "thin" },
right: { style: "thin" },
};
for (const key in sheet) {
if (Object.hasOwnProperty.call(sheet, key)) {
const element = sheet[key];
if (typeof element === "object") {
const index = Number(key.slice(1)) - 1;
let alignment = {
horizontal: "center", // 所有单元格右对齐
vertical: "center", // 所有单元格垂直居中
wrapText: true, //自动换行 需申报物品
};
element.s = {
alignment: alignment,
font: {
name: "宋体",
sz: 12,
italic: false,
underline: false,
},
border: borderAll,
fill: {
fgColor: { rgb: "FFFFFFFF" },
},
};
if (index === 0) {
element.s.font.bold = true; // 加粗
}
// 标题的样式
if (index === 2) {
// element.s.font.bold = true; // 加粗
// element.s.fill.fgColor = { rgb: "FFCCFFFF" };
}
}
}
}
// 表头的样式设置
sheet["A1"].s.alignment.horizontal = "center";
sheet["A1"].s.font.underline = false;
sheet["A1"].s.font.sz = 18;
sheet["A1"].s.border = noBorder;
// 单元格的列宽
sheet["!cols"] = [
{ wpx: 37 },
{ wpx: 87 },
{ wpx: 45 },
{ wpx: 69 },
{ wpx: 176 },
{ wpx: 71 },
{ wpx: 53 },
{ wpx: 73 },
{ wpx: 51 },
];
sheet["!rows"] = [
{ hpx: 47 },
{ hpx: 63 },
{ hpx: 48 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 24 },
{ hpx: 50 }, // 19行 - 实际 18(索引)
{ hpx: 34 },
{ hpx: 46 },
{ hpx: 87 },
];
// r:列 c:行 s:开始 e:结束
sheet["!merges"] = [
{ e: { c: 7, r: 0 }, s: { c: 0, r: 0 } },
{ e: { c: 7, r: 1 }, s: { c: 0, r: 1 } },
{ e: { c: 7, r: 18 }, s: { c: 0, r: 18 } },
{ e: { c: 7, r: 19 }, s: { c: 0, r: 19 } },
{ e: { c: 7, r: 20 }, s: { c: 0, r: 20 } },
{ e: { c: 7, r: 21 }, s: { c: 0, r: 21 } },
{ e: { c: 8, r: 1 }, s: { c: 8, r: 17 } },
];
return sheet;
},
},
computed: {},
watch: {},
mounted() {},
};
</script>
<style scoped>
</style>