一. 应用机制
xlsx-style 修改样式的机制 就是选中哪一行,那一列或者哪一个 然后去修改 比如表格最左上角的一个格子 坐标是(0, 0)下标 也可以叫做 A1 选中之后 可以修改其样式
二. 实战讲解
1. 下载依赖
npm install xlsx-style -S
首先下载依赖到项目
2. 引入到项目
import * as XLSX from 'xlsx'
3. 创建导出表格
为什么说是创建导出表格而不是表格呢,是因为导出表格跟原本页面展示的表格可能不一样,打比方我导出页面表格比普通的表格下方多一行注释 等等,如果导出表格跟页面展示的一样,则可以用改表格,否则创建一个新表格 v-show="false" 也就是隐藏掉,用来导出, 上代码
html"><el-table :data="tableDatas" border style="margin-left: 5%;width: 84%;" id="report-table"
:header-cell-style="{ 'text-align': 'center' }" height="70vh" @row-dblclick="rowDblclick"
:cell-style="{ 'text-align': 'center' }" v-show="false">
<el-table-column :label="time + req.source + '检查问题统计报表'">
<el-table-column label="序号" align="center" width="100">
<template slot-scope="scope">
<span v-if="scope.row.index"> {{ scope.row.index }} </span>
<span v-else>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column v-if="show('zdlb')" prop="caseTypeDetail" label="问题类别" width="300">
</el-table-column>
<el-table-column v-if="show('zdqyS')" prop="syncRoad" label="重点区域" width="300">
<template slot-scope="scope">
{{ scope.row.syncRoad }}
</template>
</el-table-column>
<el-table-column v-if="show('zdqyC')" prop="***munity" label="重点区域" width="300">
<template slot-scope="scope">
<span v-if="scope.row.***munity == '合并'"> {{ scope.row.***munity }} </span>
<selectTag v-else :type="***munityData" :value="scope.row.***munity"></selectTag>
</template>
</el-table-column>
<el-table-column prop="total" label="总数" width="100">
</el-table-column>
<el-table-column label="按时整改" width="200">
<template slot-scope="{}" slot="header">
<span>按时整改</span>
<el-tooltip class="item" effect="dark" placement="top">
<i class="el-icon-question" style="vertical-align: middle;color:red"></i>
<div slot="content">
<p>Tips:在规定时限内完成整改的案件</p>
</div>
</el-tooltip>
</template>
<el-table-column prop="ontimeNum" label="数量" width="100">
</el-table-column>
<el-table-column prop="ontimeScore" label="扣分" width="100">
</el-table-column>
</el-table-column>
<el-table-column label="限时整改" width="200">
<template slot-scope="{}" slot="header">
<span>限时整改</span>
<el-tooltip class="item" effect="dark" placement="top">
<i class="el-icon-question" style="vertical-align: middle;color:red"></i>
<div slot="content">
<p>Tips:未在规定时限内完成整改的案件</p>
</div>
</el-tooltip>
</template>
<el-table-column prop="timelimitNum" label="数量" width="100">
</el-table-column>
<el-table-column prop="timelimitScore" label="扣分" width="100">
</el-table-column>
</el-table-column>
<el-table-column label="超期整改" width="200">
<template slot-scope="{}" slot="header">
<span>超期整改</span>
<el-tooltip class="item" effect="dark" placement="top">
<i class="el-icon-question" style="vertical-align: middle;color: red"></i>
<div slot="content">
<p>Tips:超过规定时限内整改的案件</p>
</div>
</el-tooltip>
</template>
<el-table-column prop="overdueNum" label="数量" width="100">
</el-table-column>
<el-table-column prop="overdueScore" label="扣分" width="100">
</el-table-column>
</el-table-column>
<el-table-column prop="a***umulatedScore" label="累计扣分" width="100">
<template slot-scope="scope">
{{ scope.row.a***umulatedScore ? parseFloat(scope.row.a***umulatedScore).toFixed(2) : "" }}
</template>
</el-table-column>
<el-table-column label="备注" width="100">
</el-table-column>
</el-table-column>
</el-table>
上面是源代码 可能过于复杂 我给大家上精简版
<el-table :data="tableDatas" border id="report-table" v-show="false">
<el-table-column :label="time + req.source + '检查问题统计报表'">
<el-table-column label="序号" align="center" width="100">
<template slot-scope="scope">
<span v-if="scope.row.index"> {{ scope.row.index }} </span>
<span v-else>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column label="备注" width="100">
</el-table-column>
</el-table-column>
</el-table>
重要的是:绑定在 el-table 这个标签里的 id
4. 导出事件
事件内 我们一行一行细讲 首先 获取当前导出表格的数据 这个时候就要用上之前导出表格上方绑定的 id 了 我们声明一个 wb 去接收 表格内数据转化的二进制 blob
var wb = XLSX.utils.table_to_book(document.querySelector("#report-table"));
我们可以打印一下 wb 看看里面有什么东西
而我们所需要修改的表格则在 wb.Sheets 下, 我们在打印一下 wb.Sheets
如果你导出表格只有一张的话 wb.Sheets 下就只有 Sheet1 一个参数 如果有其他表的话 则有:Sheet2, Sheet3 ... 以此类推
Sheet1 下方参数
参数 | 表达含义 |
!cols | 代表每一列,数据格式为数组,比如 [{wpx:100}, {wpx: 100}], 则表示为前两列的宽为 100px |
!merge | 合并单元格,数据格式为数组 [{s:{r:0,c:0},e:{r:0,c:6}}] , s(start)为开始单元格坐标,e(end)为结束单元格坐标,r (row)行,c(col)列,这里的例子代表合并第0行第0到 第0行第6个单元格 |
A1 | A1 代表单元格第一行第一个 往右走则是 B1, C1...这个可以参照导出表格里的 A列第一行 每个单元格都有其格式 {t:"s", s: {}, v:"" }, t(type)为类型 其参数有:n(number数字类型),s(string字符串类型);s(style)里面参数为样式,你想要修改单元格的内部样式,v(value)是单元格内容 |
知道参数 那么我们就继续上代码了
比方:我要修改前24列的单元格宽
// 表Sheet1
wb.Sheets.Sheet1["!cols"] = [];
// 动态添加前24列 宽为140px
for (let a = 0; a < 24; a++) {
wb.Sheets.Sheet1["!cols"].push({
wpx: 140,
})
}
表格添加边框并修改字体
let arr = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
// 循环渲染表格样式
arr.forEach((item) => {
for (let i = 1; i < 7 + this.tableData.length; i++) {
let str = (item + i).toString();
if (wb.Sheets.Sheet1[str]) {
wb.Sheets.Sheet1[str].s = {
font: {
name: "宋体",
sz: 14,
// bold: true,
// color: { rgb: "FC5531" }
},
border: {
top: {
style: 'thin',
color: {
auto: 1
}
},
left: {
style: 'thin',
color: {
auto: 1
}
},
right: {
style: 'thin',
color: {
auto: 1
}
},
bottom: {
style: 'thin',
color: {
auto: 1
}
}
},
alignment: {
// 居中
horizontal: "center",
vertical: "center",
indent: 0,
},
}
}
})
})
先循环 arr 再循环 this.tableData.length 是因为 循环相加之后 拼凑成 A1 A2 B1 B2 ... 这样类型的 wb.Sheets.Sheet1[str].s 则是修改它的样式
手动合并单元格(手动合并可能会导致表格报问题)
// 手动合并 最后三行注释
wb.Sheets.Sheet1["!merges"].push({
e: {
r: parseInt(_tableData.length + 2), c: 0
},
s: {
r: parseInt(_tableData.length + 4), c: 5
}
})
这个点 是 即可 还得研究一下 怎么解决
结束 打完 手工