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

  1. <!-- add the shim first -->
  2. <script type="text/javascript" src="/XLSX/shim.min.js"></script>
  3. <!-- after the shim is referenced, add the library -->
  4. <script type="text/javascript" src="/XLSX/xlsx.full.min.js"></script>
  5. <script type="text/javascript" src="/XLSX/xlsx.bundle.js"></script>
复制代码
vue页面脚本
  1. <template>  
  2.         <a-modal v-model="ShowExportWin" title=" Export Or Print Data"  :dialog-style="{ top: '10px' }" :width="'80%'">
  3.                 <a-button @click="ExportExcel()">导出到Excel</a-button>
  4.                 <div id="excelDataContainer" v-html="TableHTML" style="overflow: auto;width: 100%; border: 1px solid black;"></div>
  5.         </a-modal>
  6. </template>
  7. <script  >
  8. // import html2excel from 'html2excel';
  9. // import XLSX from 'xlsx';
  10. // import * as XLSX from 'xlsx';
  11. // import { utils, writeFileXLSX } from 'xlsx-js-style'
  12. // import XLSX from '@/components/xlsx.full.min.js';
  13. //建议不要在这里import , 一但把XLSX打包到一起,  系统将反应迟钝. 太大了.
  14. export default {
  15.     name: "PrintOrExport",
  16.     data() {
  17.         return {      
  18.                 ShowExportWin :false,
  19.                 MasterTableName: "",
  20.                 SlaveTableName: "",
  21.                 TableHTML:"",
  22.                 MasterFields: [],
  23.                 SlaveFields: [],
  24.                 MasterData: {
  25.                     // "订单编号": "20250104001",
  26.                     // "客户名称": "李四",
  27.                     // "下单时间": "2025-01-04 14:30:00"
  28.                 },
  29.                 SlaveDatas: [
  30.                     // { "商品名称": "笔记本电脑", "数量": 1, "单价": 5000 },
  31.                     // { "商品名称": "鼠标", "数量": 2, "单价": 50 }
  32.                 ],
  33.             }
  34.     },
  35.     mounted() {
  36.       
  37.     },
  38.     methods: {
  39.         ExportExcel()
  40.         {
  41.                 const table = document.getElementById('excelDataContainer').firstChild;
  42.                 const wb = XLSX.utils.book_new();
  43.                 const ws = XLSX.utils.table_to_sheet(table);
  44.                 var maxColIndex =  0;
  45.                 // 遍历表格的所有行和列
  46.                 for (let rowIndex = 0; rowIndex < table.rows.length; rowIndex++) {
  47.                     const row = table.rows[rowIndex];
  48.                     for (let colIndex = 0; colIndex < row.cells.length; colIndex++) {
  49.                         const cell = row.cells[colIndex];
  50.                             var cellObj = {
  51.                                 v: cell.textContent,
  52.                                 t:'s',
  53.                                 s: {
  54.                                     alignment: { wrapText: true, horizontal: 'center', vertical: 'center' },
  55.                                     border: { top: { style: 'thin' }, bottom: { style: 'thin' }, left: { style: 'thin' }, right: { style: 'thin' } },
  56.                                 },
  57.                             };
  58.                             if (cell.tagName === 'TH') {
  59.                                 // 处理表头
  60.                                 cellObj.s.fill= { fgColor: { rgb: '0000FF' } };
  61.                                 cellObj.s.font= { color: { rgb: 'FFFFFF' } };
  62.                                 // cellObj.s.border= { top: { style: 'thin' }, bottom: { style: 'thin' }, left: { style: 'thin' }, right: { style: 'thin' } };
  63.                                 cellObj.s.alignment.horizontal= 'right';
  64.                                 // cellObj.s.alignment= { wrapText: true };
  65.                             }
  66.                             const cellRef = XLSX.utils.encode_cell({ c: colIndex, r: rowIndex });
  67.                             ws[cellRef] = cellObj;
  68.                             if (colIndex > maxColIndex) {
  69.                                 maxColIndex = colIndex;
  70.                             }
  71.                     }
  72.                     
  73.                 }
  74.                 // 设置列的最大宽度不超过150
  75.                 const numCols = maxColIndex;
  76.                 const cols = Array.from({ length: numCols }, () => ({ wch: 150 / 7.5 })); // 大致计算,1字符宽度约7.5px
  77.                 ws['!cols'] = cols;
  78.             
  79.                 XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
  80.                 XLSX.writeFile(wb, this.MasterTableName + "_" + this.MasterData["__id"] + '_TableData.xlsx');
  81.         },
  82.         
  83.          
  84.         exportData(MasterTableName,SlaveTableName,MasterFields, SlaveFields,  MasterData, SlaveDatas) {
  85.             this.MasterTableName = MasterTableName;
  86.             this.SlaveTableName = SlaveTableName;
  87.             this.MasterFields = [...MasterFields];
  88.             
  89.             this.SlaveFields = [...SlaveFields];
  90.             this.MasterData = {...MasterData};
  91.             this.SlaveDatas = [...SlaveDatas];
  92.             this.ShowExportWin = true;
  93.             
  94.             console.log("mounted");
  95.             this.RenderTableData();
  96.             //this.$forceUpdate();
  97.             console.log("exportData");  
  98.         },
  99.         RenderTableData(){
  100.             this.TableHTML = this.generateExcelHTML();   
  101.         },
  102.         H2V(keys,details_count){
  103.                 var COL_COUNTR = 3;//定死3列与界面显示一致 Math.floor(details_count/2); //计算有几列, 一个字段占2列.
  104.                 var col = 1;
  105.                 var col_count = Math.floor(keys.length / COL_COUNTR);//one_column_length
  106.                 var duoyu = keys.length % COL_COUNTR;
  107.             
  108.                 var cut1 = col_count;
  109.                 var cut2 = col_count;
  110.                 var cut3 = col_count;
  111.                 //2.先把数组分割成3列
  112.                 if(duoyu==1){
  113.                     cut1 = col_count+1;
  114.                 }else if(duoyu==2){
  115.                     cut1  = col_count+1;
  116.                     cut2  = col_count+1;
  117.                 }
  118.                 var colarr1 = keys.splice(0, cut1) ;//this.splitArray(keys, cut1);
  119.                 var colarr2 = keys.splice(0, cut2) ;//this.splitArray(keys, cut2);  
  120.                 var colarr3 = keys.splice(0, cut3) ;//this.splitArray(keys, cut3);
  121.                 // debugger;
  122.                 // 再把每列的数组合并成一个数组
  123.                 var newKeys =[];
  124.                 for(var i=0;i<colarr1.length;i++)
  125.                 {
  126.                     newKeys.push(colarr1[i]);
  127.                     if(i < colarr2.length){
  128.                         newKeys.push(colarr2[i]);
  129.                     }
  130.                     if(i < colarr3.length){
  131.                         newKeys.push(colarr3[i]);
  132.                     }
  133.                 }
  134.                 return newKeys;
  135.         },
  136.         // 生成主表单的HTML表格行结构
  137.         generateMainFormTableRow(data,keys) {
  138.             //var keys = Object.keys(data);
  139.             keys = this.H2V(keys);
  140.             let rowHTML = '<tr>';
  141.             for (var i = 0; i < keys.length; i++) {
  142.                 if (i > 0 && i % 3 === 0) {
  143.                     rowHTML += '</tr><tr>';
  144.                 }
  145.                 const key = keys[i];
  146.                 rowHTML += `<th class="mHead">${key}</th><td class="mRow">${data[key]}</td>`;
  147.             }
  148.             
  149.             if(keys.length % 3 == 1){
  150.                 rowHTML += '<th class="mHead"> </th><td class="mRow"> </td>';
  151.                 rowHTML += '<th class="mHead"> </th><td class="mRow"> </td>';
  152.             }else if(keys.length % 3 == 2){
  153.                 rowHTML += '<th class="mHead"> </th><td class="mRow"> </td>';
  154.             }
  155.             rowHTML += '</tr>';
  156.             // debugger;
  157.             return rowHTML;
  158.         },
  159.         // 生成明细数据的HTML表格行结构
  160.         generateDetailTableRow(data,keys) {
  161.             let rowHTML = '<tr>';
  162.             keys.forEach(key => {
  163.                 rowHTML += `<td class="dRow">${data[key]}</td>`;
  164.             });
  165.             rowHTML += '</tr>';
  166.             return rowHTML;
  167.         },
  168.         isHiddenContorl(f) {
  169.             if (f.FieldName.indexOf("_") >= 0 )   return true; //_开头的字段 不显示//0和-1 不显示
  170.             if (f.DisplayWidth <= 0) return true; //显示宽度为0 不显示
  171.             if (f.EditControl == "隐藏控件") return true;
  172.             if (f.EditControl == "None") return true;
  173.             if (f.EditControl == "无") return true;
  174.             if (f.EditControl == "") return true;
  175.             if (f.EditControl == null) return true;
  176.             if (f.EditControl == undefined) return false;
  177.             if (f.FieldName == null || f.FieldName == undefined || f.FieldName == "") return false;
  178.             return false;
  179.         },
  180.         getNotHideFields(fields) {
  181.             var tempArray = [];
  182.             //先取需要显示的字段
  183.             for (var i = 0; i < fields.length; i++)
  184.             {
  185.                 var f = fields[i];
  186.                 if(this.isHiddenContorl(f)){
  187.                     continue;
  188.                 }
  189.                 tempArray.push(f.FieldName);
  190.             }
  191.             return tempArray;
  192.         },
  193.         // 生成明细数据的HTML表格头结构
  194.         generateDetailTableHeader(keys) {
  195.             let headHTML = '<tr>';
  196.             keys.forEach(key => {
  197.                 headHTML += `<th  class="dHead">${key}</th>`;
  198.             });
  199.             headHTML += '</tr>';
  200.             return headHTML;
  201.         },
  202.     // 生成完整的HTML表格结构,包含主表单和明细数据
  203.       generateExcelHTML() {
  204.             var tableHTML = '<table border="1">';
  205.             
  206.             var masterFields = this.getNotHideFields(this.MasterFields);
  207.             var slaveFields = this.getNotHideFields(this.SlaveFields);
  208.             // 主表单表头
  209.             //tableHTML += '<tr><th colspan="2">' + this.MasterTableName + '</th></tr>';
  210.             tableHTML += this.generateMainFormTableRow(this.MasterData,masterFields);
  211.             // 明细表头
  212.             // tableHTML += '<tr><th colspan="3">明细</th></tr>';
  213.             // tableHTML += '<tr><th>商品名称</th><th>数量</th><th>单价</th></tr>';
  214.             tableHTML += this.generateDetailTableHeader(slaveFields);
  215.             // 明细数据行
  216.             this.SlaveDatas.forEach(item => {
  217.                 tableHTML += this.generateDetailTableRow(item,slaveFields);
  218.             });
  219.             tableHTML += '</table>';
  220.             return tableHTML;
  221.         },
  222.         printData() {   
  223.             console.log("printData");
  224.         }
  225.     }
  226. }   
  227. </script>
  228. <style>
  229. .mHead,.mRow,.dRow,.dHead{
  230.    
  231.     border: 1px solid black;
  232.     padding: 5px;
  233.     max-width: 200px;
  234. }
  235. .mRow{
  236.     border: 1px solid black;
  237. }
  238. .dRow{
  239.     border: 1px solid black;
  240. }
  241. .mHead,.dHead{
  242.     background-color: #3278fc;
  243.     color: white;
  244. }
  245. </style>
复制代码
应用demo
  1. import PrintOrExport from "./PrintOrExport.vue";  
  2. <PrintOrExport ref="PrintOrExportVue"></PrintOrExport>
  3. 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