实现:el-table导出word、excel、pdf文档工具类,ts文件

一、导出相关库

npm install jspdf jspdf-autotable file-saver html-docx-js

 二、因为jspdf导出的中文会乱码,所以要引入字体

        1.访问地址,clone下拉项目 Gitee 极速下载/jspdf

        2.打开项目找到 jspdf ->fontconverter文件夹,在浏览器打开fontconverter.html网页

        3.在网页中选择字体文件,点击create后,会生成js文件。注:字体文件,在自己电脑c盘有,也可以自己下载。因为我的项目是ts,所以将js文件改成了ts文件

        

        4.将文件放到工具类同一级目录

         

三、完整代码,可以直接用或者根据自己的需求修改html样式

import htmlDocx from 'html-docx-js/dist/html-docx';
import jsPDF from 'jspdf';
import 'jspdf-autotable';
import FileSaver from 'file-saver';
import './songti-normal'


// 导出 Excel
export function exportExcel(tableId: string, fileName: string, projectName: any,unit: any) {
  const ctime = new Date().toISOString().replace(/[-T:\.Z]/g, '');
  var elTable = document.querySelector('#'+tableId);
  var htmlTable = convertElTableToHtmlTableExcel(elTable, fileName, projectName, unit);

  // 创建 Blob 对象
  const blob = new Blob([htmlTable], { type: 'application/vnd.ms-excel' });
  // 创建链接并触发下载
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = fileName+ctime+'.xlsx'; // 设置默认文件名
  link.style.display = "none";
  document.body.appendChild(link);
  link.click();
  window.URL.revokeObjectURL(link.href);
}

// 导出 Word
export async function exportWord(tableId: string, fileName: string,projectName: undefined,unit: string | undefined) {
  var elTable = document.querySelector('#'+tableId);
  var htmlTable = convertElTableToHtmlTableWord(elTable,fileName,projectName,unit);
  let converted = htmlDocx.asBlob(htmlTable);
  const ctime = new Date().toISOString().replace(/[-T:\.Z]/g, '');
  FileSaver.saveAs(converted, fileName + ctime + '.docx');
}

// 导出 PDF
export async function exportPDF(tableId: string, fileName: string,projectName,unit) {
 const ctime = new Date().toISOString().replace(/[-T:\.Z]/g, '');
  var elTable = document.querySelector('#'+tableId);
  var htmlTable = convertElTableToHtmlTablePdf(elTable);
  // 使用 jsPDF 创建一个新的文档
  const doc = new jsPDF();
  doc.setFont("songti");//设置字体,这里字体名字为刚才下载文件的名字
  const addHeader = (title,leftInfo,rightInfo) => {
    doc.setFontSize(12);
    doc.text(title, doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' });
    doc.text('工程名称:' + leftInfo, 15, 35); // 左侧信息
    if (rightInfo != '') { 
      doc.text('单位:'+rightInfo, doc.internal.pageSize.getWidth() - 15, 35, { align: 'right' }); // 右侧信息
    }
    
  };
  
  addHeader(fileName,projectName,unit)
  const startY = 36;
  doc.autoTable({
    html: htmlTable,
    // startY: startY, // 起始位置,单位为 mm,从顶部往下算起
    margin: { top: startY}, // 设置页面上方的边距
    tableWidth: 'auto', // 自动调整表格宽度以适应页面宽度
    headStyles: { fillColor: [240, 240, 240], textColor: [0, 0, 0],fontStyle: 'bold', halign: 'center', lineWidth: 0.1  },
    styles: {
        font: "songti", //字体
      fontStyle: "normal", //字体样式
      lineWidth: 0.1 
    },
    theme: 'grid', // 可选的主题样式
    didDrawPage: (data) => {
      // 在每一页上方添加大标题
      if (data.pageNumber > 1) {
        addHeader(fileName, projectName, unit)
      }
    },

  });
  doc.save(fileName+ctime+'.pdf');
}

//导出pdf   e-table转html
function convertElTableToHtmlTablePdf(elTable: Element | null) {
  // Example function to convert el-table to HTML table
    // 从 el-table 中提取表头和数据
  const thead = elTable.querySelector('thead');
  const tbody = elTable.querySelector('tbody');

  // 创建一个新的 HTML 表格元素
  const htmlTable = document.createElement('table');
  htmlTable.appendChild(thead.cloneNode(true)); // 复制表头
  htmlTable.appendChild(tbody.cloneNode(true)); // 复制数据

  return htmlTable;
}

//导出word   e-table转html
function convertElTableToHtmlTableWord(elTable: Element | null,title: string,infoLeft: undefined,infoRight: string | undefined) {
  if (!elTable) return '';

  // 获取 el-table 的表头数据,包括多级表头
  const theadRows = elTable.querySelectorAll('thead tr');
  // 获取 el-table 的数据行
  const tbodyRows = elTable.querySelectorAll('tbody tr');
  let length = getTotalColumnCount(theadRows[0])
  // 开始构建 HTML 表格的字符串,设置表格整体样式和边框样式
  let htmlTable = '<table style="border-collapse: collapse; border: 1px solid black;"><thead>'
  htmlTable += `<tr><th colspan="${length}" style="width:306.2000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid rgb(255,255,255);
mso-border-left-alt:0.5000pt solid rgb(255,255,255);border-right:1.0000pt solid rgb(255,255,255);mso-border-right-alt:0.5000pt solid rgb(255,255,255);
border-top:1.0000pt solid rgb(255,255,255);mso-border-top-alt:0.5000pt solid rgb(255,255,255);border-bottom:1.0000pt solid rgb(255,255,255);
mso-border-bottom-alt:0.5000pt solid rgb(255,255,255);background:rgb(255,255,255); text-align: center;">${title}</th></tr>`
  htmlTable += '<tr>'
  htmlTable += `<th colspan="${ length-Math.floor(length / 2)}" style="width:306.2000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid rgb(255,255,255);
mso-border-left-alt:0.5000pt solid rgb(255,255,255);border-right:1.0000pt solid rgb(255,255,255);mso-border-right-alt:0.5000pt solid rgb(255,255,255);
border-top:1.0000pt solid rgb(255,255,255);mso-border-top-alt:0.5000pt solid rgb(255,255,255);border-bottom:none;
mso-border-bottom-alt:none;background:rgb(255,255,255);text-align: left;">工程名称:${infoLeft}</th>`;
  if (infoRight != '') {
    htmlTable += `<th colspan="${Math.floor(length / 2)}" style="width:306.2000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid rgb(255,255,255);
mso-border-left-alt:0.5000pt solid rgb(255,255,255);border-right:1.0000pt solid rgb(255,255,255);mso-border-right-alt:0.5000pt solid rgb(255,255,255);
border-top:1.0000pt solid rgb(255,255,255);mso-border-top-alt:0.5000pt solid rgb(255,255,255);border-bottom:none;
mso-border-bottom-alt:none;background:rgb(255,255,255);text-align: right;">单位:${infoRight}</th>`;
  } else { 
    htmlTable += `<th colspan="${Math.floor(length / 2)}" style="width:306.2000pt;padding:0.0000pt 5.4000pt 0.0000pt 5.4000pt ;border-left:1.0000pt solid rgb(255,255,255);
mso-border-left-alt:0.5000pt solid rgb(255,255,255);border-right:1.0000pt solid rgb(255,255,255);mso-border-right-alt:0.5000pt solid rgb(255,255,255);
border-top:1.0000pt solid rgb(255,255,255);mso-border-top-alt:0.5000pt solid rgb(255,255,255);border-bottom:none;
mso-border-bottom-alt:none;background:rgb(255,255,255);text-align: right;"></th>`;
  }
  htmlTable += '</tr>';

    // 处理多级表头
    theadRows.forEach(row => {
        htmlTable += '<tr>';
        const columns = row.querySelectorAll('th');
        columns.forEach(column => {
            const colspan = column.getAttribute('colspan') || '1';
            const rowspan = column.getAttribute('rowspan') || '1';
            htmlTable += `<th colspan="${colspan}" rowspan="${rowspan}" style="border: 1px solid black;">${column.innerText}</th>`;
        });
        htmlTable += '</tr>';
    });

    htmlTable += '</thead><tbody>';

    // 构建数据行
    tbodyRows.forEach(row => {
        htmlTable += '<tr>';
        const cells = row.querySelectorAll('td');
        cells.forEach(cell => {
            if (cell.querySelector('div')) {
                htmlTable += `<td style="border: 1px solid black;">${cell.querySelector('div').innerHTML}</td>`;
            } else {
                htmlTable += `<td style="border: 1px solid black;">${cell.innerText}</td>`;
            }
        });
        htmlTable += '</tr>';
    });

    htmlTable += '</tbody></table>';

    return htmlTable;
}



function convertElTableToHtmlTableExcel(elTable: Element | null,title: string,infoLeft: undefined,infoRight: string | undefined) {
  if (!elTable) return '';

  // 获取 el-table 的表头数据,包括多级表头
  const theadRows = elTable.querySelectorAll('thead tr');
  // 获取 el-table 的数据行
  const tbodyRows = elTable.querySelectorAll('tbody tr');
  let length = getTotalColumnCount(theadRows[0])
    // 开始构建 HTML 表格的字符串,设置表格整体样式和边框样式
  let htmlTable = `<html><head><meta charset="UTF-8"></head><body>`;
  htmlTable += '<table><thead><tr>';
  htmlTable += `<th colspan="${length}" >${title}</th>`; 
  htmlTable += '</tr><tr>'
   htmlTable += `<th colspan="${ length-Math.floor(length / 2)}" style="text-align:left">工程名称:${infoLeft}</th>`;
  if (infoRight != '') {
    htmlTable += `<th colspan="${Math.floor(length / 2)}" style="text-align:right">单位:${infoRight}</th>`;
  } else { 
    htmlTable += `<th colspan="${Math.floor(length / 2)}" style="text-align:right"></th>`;
  }
  htmlTable += '</tr></thead></table>';
  htmlTable += '<table style="border-collapse: collapse; border: 1px solid black;"><thead>';
 
    // 处理多级表头
    theadRows.forEach(row => {
        htmlTable += '<tr>';
        const columns = row.querySelectorAll('th');
        columns.forEach(column => {
            const colspan = column.getAttribute('colspan') || '1';
            const rowspan = column.getAttribute('rowspan') || '1';
            htmlTable += `<th colspan="${colspan}" rowspan="${rowspan}" style="border: 1px solid black;">${column.innerText}</th>`;
        });
        htmlTable += '</tr>';
    });

    htmlTable += '</thead><tbody>';

    // 构建数据行
    tbodyRows.forEach(row => {
        htmlTable += '<tr>';
        const cells = row.querySelectorAll('td');
        cells.forEach(cell => {
            if (cell.querySelector('div')) {
                htmlTable += `<td style="border: 1px solid black;">${cell.querySelector('div').innerHTML}</td>`;
            } else {
                htmlTable += `<td style="border: 1px solid black;">${cell.innerText}</td>`;
            }
        });
        htmlTable += '</tr>';
    });

    htmlTable += '</tbody></table></body></html>';

    return htmlTable;
}

//获取总列数
function getTotalColumnCount(theadRows) {
    let rowColumns = 0;
    const columns = theadRows.querySelectorAll('th');
    columns.forEach(column => {
      const colspan = column.getAttribute('colspan') || 1;
      rowColumns += Number(colspan)
    });
    return rowColumns;
}

四、html样式 不知道怎么调整,可以在wps建一个模版保存为html格式,打开文件,f12查看样式进行修改

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值