vue + elment ui打印表格数据
主要的原理就是 在vue项目中 通过调用浏览器自带的打印功能,完成对table数据的打印 解决表格错位 以及elment ui 双重表头的问题
封装一下打印方法以便于在项目中调用
export function PrintForm(id) {
// 空页面
let printStr = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head>";
// 定义element-ui table组件的样式
const tabStyle = `<style>
table{width:100%;display:table-cell!important;box-sizing:border-box;}
.el-table__header,.el-table__body,.el-table__footer{width:100%!important;border-collapse: collapse;text-align:center;}
table,table tr th, table tr td { border:1px solid #ddd;color:#606266;word-wrap:break-word}
table tr th,table tr td{padding:5 10px;word-wrap:break-word }
.el-table__body, tr td .cell{width:100%!important}
.el-table th.gutter{display: none;}
.el-table colgroup.gutter{display: none;}
</style><body>`;
let content = "";
// 获取名为传入id的 dom元素内的内容
const html = document.getElementById(id).innerHTML;
// 新建一个 DOM
const div = document.createElement("div");
const printDOMID = "printDOMElement";
div.id = printDOMID;
div.innerHTML = html;
// elment ui 的表格中表头与内容是用的两个表格去渲染的 所以这里要做拼接
// 提取第一个表格的内容 即表头
const ths = div.querySelectorAll(".el-table__header-wrapper th");
const ThsTextArry = [];
for (let i = 0, len = ths.length; i < len; i++) {
if (ths[i].innerText !== "") ThsTextArry.push(ths[i].innerText);
}
// 删除多余的表头
div.querySelector(".hidden-columns").remove();
// 第一个表格的内容提取出来后已经没用了 删掉
div.querySelector(".el-table__header-wrapper").remove();
// 将第一个表格的内容插入到第二个表格
let newHTML = "<tr>";
for (let i = 0, len = ThsTextArry.length; i < len; i++) {
newHTML +=
'<td style="text-align: center; font-weight: bold">' +
ThsTextArry[i] +
"</td>";
}
newHTML += "</tr>";
div.querySelector(".el-table__body-wrapper table").insertAdjacentHTML("afterbegin", newHTML);
let str = div.innerHTML;
// 拼接空页面+style样式+dom内容
content = content + str;
printStr = printStr + tabStyle + content + "</body></html>";
// 打开新页面
let pWin = window.open("_blank");
// 将内容赋值到新页面
pWin.document.write(printStr);
// 使用setTimeout,等页面dom元素渲染完成后再打印。
setTimeout(() => {
pWin.print(); // 调用打印功能。
pWin.close(); // 关闭 打印创建的当前页面
}, 300);
}
在main.js中引入打印方法并挂载到全局
// 全局引入打印&导出表格
import { PrintForm } from "@/utils/tools";
Vue.prototype.PrintForm = PrintForm;
在需要打印的页面 需要编辑一个表格数据 作为打印的表格
原表格
<!-- 表格数据 -->
<el-table :data="tableData" row-key="id" border height="100%">
<el-table-column type="index" label="序号" width="50" fixed="left">
</el-table-column>
<el-table-column prop="code" label="员工编号"> </el-table-column>
<el-table-column prop="name" label="姓名"> </el-table-column>
<el-table-column prop="storeName" label="所属门店"> </el-table-column>
<el-table-column prop="status" label="员工状态">
<template slot-scope="scope">
<span>{{
scope.row.status == 1
? "在职"
: scope.row.status == 0
? "离职"
: "未知错误"
}}</span>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope" fixed="right">
<el-button
type="text"
size="small"
@click="handleOperation(scope.row, 'edit')"
>编辑</el-button
>
<el-button
type="text"
size="small"
@click="handleOperation(scope.row, 'delete')"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
打印表格
<!-- 打印表格 -->
<el-table
v-show="0 > 1"
id="printData"
:data="tableData"
border
style="width:100%"
>
<el-table-column type="index" label="序号" width="50">
</el-table-column>
<el-table-column width='100' prop="code" label="员工编号"> </el-table-column>
<el-table-column prop="name" label="姓名"> </el-table-column>
<el-table-column prop="storeName" label="所属门店"> </el-table-column>
<el-table-column prop="status" label="员工状态">
<template slot-scope="scope">
<span>{{
scope.row.status == 1
? "在职"
: scope.row.status == 0
? "离职"
: "未知错误"
}}</span>
</template>
</el-table-column>
</el-table>
需要注意的是:
打印表格必须要去掉表头中的fixed属性
每一列的宽度可以通过 width 来控制 例如
<el-table-column width='100' prop="code" label="员工编号"> </el-table-column>
接下来 就可以直接绑定点击事件
<el-button type="primary" size="mini" @click="handlePrint" >打印</el-button>
<script>
export default {
data() {
return {
// 表格数据
tableData: []
};
},
methods: {
// 打印
handlePrint() {
this.PrintForm("printData");
}
};
</script>
初入前端行业,能做到只有这么多,方法是麻烦了一点,但好在还是能解决项目中的这个需求
代码中有不足之处,或者有更好的方法,还望各位路过的前辈指点一二