ToB企服应用市场:ToB评测及商务社交产业平台
标题:
html表格table导出excel,主从表格式,带样式.主动分列
[打印本页]
作者:
王柳
时间:
2025-1-7 23:17
标题:
html表格table导出excel,主从表格式,带样式.主动分列
html的table导出成excel, vue模板
项目使用xlsx-js-style
源代码从https://github.com/gitbrent/xlsx-js-style/releases/tag/v1.2.0 下载
用内里的dist目次下的文件即可. 复制到vue项目的public目次下的XLSX目次下.
在index.hml中引入js脚本, 为啥要在这里引入? 是由于这里引入可以极大的减少打包时间. 并且提高页面欣赏的速度. 一但把XLSX打包到一起, 系统将反应痴钝,所有我建议将这个模块的js独立使用.
把文件放入vue项目的public目次下, 打包发布后再复制到项目根目次下.
在index.hml
<!-- add the shim first -->
<script type="text/javascript" src="/XLSX/shim.min.js"></script>
<!-- after the shim is referenced, add the library -->
<script type="text/javascript" src="/XLSX/xlsx.full.min.js"></script>
<script type="text/javascript" src="/XLSX/xlsx.bundle.js"></script>
复制代码
vue页面脚本
<template>
<a-modal v-model="ShowExportWin" title=" Export Or Print Data" :dialog-style="{ top: '10px' }" :width="'80%'">
<a-button @click="ExportExcel()">导出到Excel</a-button>
<div id="excelDataContainer" v-html="TableHTML" style="overflow: auto;width: 100%; border: 1px solid black;"></div>
</a-modal>
</template>
<script >
// import html2excel from 'html2excel';
// import XLSX from 'xlsx';
// import * as XLSX from 'xlsx';
// import { utils, writeFileXLSX } from 'xlsx-js-style'
// import XLSX from '@/components/xlsx.full.min.js';
//建议不要在这里import , 一但把XLSX打包到一起, 系统将反应迟钝. 太大了.
export default {
name: "PrintOrExport",
data() {
return {
ShowExportWin :false,
MasterTableName: "",
SlaveTableName: "",
TableHTML:"",
MasterFields: [],
SlaveFields: [],
MasterData: {
// "订单编号": "20250104001",
// "客户名称": "李四",
// "下单时间": "2025-01-04 14:30:00"
},
SlaveDatas: [
// { "商品名称": "笔记本电脑", "数量": 1, "单价": 5000 },
// { "商品名称": "鼠标", "数量": 2, "单价": 50 }
],
}
},
mounted() {
},
methods: {
ExportExcel()
{
const table = document.getElementById('excelDataContainer').firstChild;
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.table_to_sheet(table);
var maxColIndex = 0;
// 遍历表格的所有行和列
for (let rowIndex = 0; rowIndex < table.rows.length; rowIndex++) {
const row = table.rows[rowIndex];
for (let colIndex = 0; colIndex < row.cells.length; colIndex++) {
const cell = row.cells[colIndex];
var cellObj = {
v: cell.textContent,
t:'s',
s: {
alignment: { wrapText: true, horizontal: 'center', vertical: 'center' },
border: { top: { style: 'thin' }, bottom: { style: 'thin' }, left: { style: 'thin' }, right: { style: 'thin' } },
},
};
if (cell.tagName === 'TH') {
// 处理表头
cellObj.s.fill= { fgColor: { rgb: '0000FF' } };
cellObj.s.font= { color: { rgb: 'FFFFFF' } };
// cellObj.s.border= { top: { style: 'thin' }, bottom: { style: 'thin' }, left: { style: 'thin' }, right: { style: 'thin' } };
cellObj.s.alignment.horizontal= 'right';
// cellObj.s.alignment= { wrapText: true };
}
const cellRef = XLSX.utils.encode_cell({ c: colIndex, r: rowIndex });
ws[cellRef] = cellObj;
if (colIndex > maxColIndex) {
maxColIndex = colIndex;
}
}
}
// 设置列的最大宽度不超过150
const numCols = maxColIndex;
const cols = Array.from({ length: numCols }, () => ({ wch: 150 / 7.5 })); // 大致计算,1字符宽度约7.5px
ws['!cols'] = cols;
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
XLSX.writeFile(wb, this.MasterTableName + "_" + this.MasterData["__id"] + '_TableData.xlsx');
},
exportData(MasterTableName,SlaveTableName,MasterFields, SlaveFields, MasterData, SlaveDatas) {
this.MasterTableName = MasterTableName;
this.SlaveTableName = SlaveTableName;
this.MasterFields = [...MasterFields];
this.SlaveFields = [...SlaveFields];
this.MasterData = {...MasterData};
this.SlaveDatas = [...SlaveDatas];
this.ShowExportWin = true;
console.log("mounted");
this.RenderTableData();
//this.$forceUpdate();
console.log("exportData");
},
RenderTableData(){
this.TableHTML = this.generateExcelHTML();
},
H2V(keys,details_count){
var COL_COUNTR = 3;//定死3列与界面显示一致 Math.floor(details_count/2); //计算有几列, 一个字段占2列.
var col = 1;
var col_count = Math.floor(keys.length / COL_COUNTR);//one_column_length
var duoyu = keys.length % COL_COUNTR;
var cut1 = col_count;
var cut2 = col_count;
var cut3 = col_count;
//2.先把数组分割成3列
if(duoyu==1){
cut1 = col_count+1;
}else if(duoyu==2){
cut1 = col_count+1;
cut2 = col_count+1;
}
var colarr1 = keys.splice(0, cut1) ;//this.splitArray(keys, cut1);
var colarr2 = keys.splice(0, cut2) ;//this.splitArray(keys, cut2);
var colarr3 = keys.splice(0, cut3) ;//this.splitArray(keys, cut3);
// debugger;
// 再把每列的数组合并成一个数组
var newKeys =[];
for(var i=0;i<colarr1.length;i++)
{
newKeys.push(colarr1[i]);
if(i < colarr2.length){
newKeys.push(colarr2[i]);
}
if(i < colarr3.length){
newKeys.push(colarr3[i]);
}
}
return newKeys;
},
// 生成主表单的HTML表格行结构
generateMainFormTableRow(data,keys) {
//var keys = Object.keys(data);
keys = this.H2V(keys);
let rowHTML = '<tr>';
for (var i = 0; i < keys.length; i++) {
if (i > 0 && i % 3 === 0) {
rowHTML += '</tr><tr>';
}
const key = keys[i];
rowHTML += `<th class="mHead">${key}</th><td class="mRow">${data[key]}</td>`;
}
if(keys.length % 3 == 1){
rowHTML += '<th class="mHead"> </th><td class="mRow"> </td>';
rowHTML += '<th class="mHead"> </th><td class="mRow"> </td>';
}else if(keys.length % 3 == 2){
rowHTML += '<th class="mHead"> </th><td class="mRow"> </td>';
}
rowHTML += '</tr>';
// debugger;
return rowHTML;
},
// 生成明细数据的HTML表格行结构
generateDetailTableRow(data,keys) {
let rowHTML = '<tr>';
keys.forEach(key => {
rowHTML += `<td class="dRow">${data[key]}</td>`;
});
rowHTML += '</tr>';
return rowHTML;
},
isHiddenContorl(f) {
if (f.FieldName.indexOf("_") >= 0 ) return true; //_开头的字段 不显示//0和-1 不显示
if (f.DisplayWidth <= 0) return true; //显示宽度为0 不显示
if (f.EditControl == "隐藏控件") return true;
if (f.EditControl == "None") return true;
if (f.EditControl == "无") return true;
if (f.EditControl == "") return true;
if (f.EditControl == null) return true;
if (f.EditControl == undefined) return false;
if (f.FieldName == null || f.FieldName == undefined || f.FieldName == "") return false;
return false;
},
getNotHideFields(fields) {
var tempArray = [];
//先取需要显示的字段
for (var i = 0; i < fields.length; i++)
{
var f = fields[i];
if(this.isHiddenContorl(f)){
continue;
}
tempArray.push(f.FieldName);
}
return tempArray;
},
// 生成明细数据的HTML表格头结构
generateDetailTableHeader(keys) {
let headHTML = '<tr>';
keys.forEach(key => {
headHTML += `<th class="dHead">${key}</th>`;
});
headHTML += '</tr>';
return headHTML;
},
// 生成完整的HTML表格结构,包含主表单和明细数据
generateExcelHTML() {
var tableHTML = '<table border="1">';
var masterFields = this.getNotHideFields(this.MasterFields);
var slaveFields = this.getNotHideFields(this.SlaveFields);
// 主表单表头
//tableHTML += '<tr><th colspan="2">' + this.MasterTableName + '</th></tr>';
tableHTML += this.generateMainFormTableRow(this.MasterData,masterFields);
// 明细表头
// tableHTML += '<tr><th colspan="3">明细</th></tr>';
// tableHTML += '<tr><th>商品名称</th><th>数量</th><th>单价</th></tr>';
tableHTML += this.generateDetailTableHeader(slaveFields);
// 明细数据行
this.SlaveDatas.forEach(item => {
tableHTML += this.generateDetailTableRow(item,slaveFields);
});
tableHTML += '</table>';
return tableHTML;
},
printData() {
console.log("printData");
}
}
}
</script>
<style>
.mHead,.mRow,.dRow,.dHead{
border: 1px solid black;
padding: 5px;
max-width: 200px;
}
.mRow{
border: 1px solid black;
}
.dRow{
border: 1px solid black;
}
.mHead,.dHead{
background-color: #3278fc;
color: white;
}
</style>
复制代码
应用demo
import PrintOrExport from "./PrintOrExport.vue";
<PrintOrExport ref="PrintOrExportVue"></PrintOrExport>
this.$refs["PrintOrExportVue"].exportData(this.MasterTableName,this.SlaveTableName,this.MasterFields, this.SlaveFields, this.MasterData, this.SlaveDatas );
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4