js 通过 exceljs 和 canvas 实现导出带水印的 excel 表

因公司需求改动, 但是因为到的地方比较多,所以单独写一个单工作表导出,实际可用多工作表的代码部分


interface IHeader {
  k: string;
  v: string;
}
export interface IParams<D extends any> {
  header: IHeader[];
  data: D[];
  sheetName: string;
}

/**
 *
 * 导出 excel(带水印) 公共方法
 * @param header v 为头,k 为对应 data 数据的 name
 * 例:
    const header = [
      {
        k: 'region',
        v: '所属区域',
      }
    ]
 * @param data 要导出的数据
    例:
    const data = [
      {
        region:'广州'
      },
      {
        region:'深圳'
      }
    ]
 * @param filename 导出的 excel 文件名称
 * @param sheetName 指定第一个工作表的名称
 * @param staff 水印名称
 * @param params 导出多个工作表
 * 格式为:
 * [{header:[],data:[],sheetName:''}]
 * @returns
 */
export const createWsSheet = <T, D>(
  header: IHeader[],
  data: T[],
  filename: string,
  sheetName = 'sheet1',
  params: IParams<D>[] = [],
  staff: string = '水印名称',
): void => {
  Message.loading('正在导出...');
  if (!((header && data) && (header.length && data.length))) {
    Message.error('导出失败');
    return;
  }
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 获取水印
  const base64 = setWatermark(staff);
  const imageId1 = workbook.addImage({ base64, extension: 'png' });
  // 创建带有红色标签颜色的工作表
  const worksheet = workbook.addWorksheet(sheetName, { properties: { tabColor: { argb: 'FFC0000' } } });
  // 生成 columns
  const columns = header.map((col: IHeader): { name: string } => ({ name: col.v }));
  // 生成 rows
  const rows = data.map((row: T): T[] => {
    return header.map(itm => isNull(row[itm.k]) ? row[itm.k] : '');
  });
  // 添加背景图片
  worksheet.addBackgroundImage(imageId1);
  // 添加数据
  worksheet.addTable({
    name: filename,
    ref: 'A1',// 表格左上角位置
    columns,
    rows
  });
  // 多工作表
  if (params && params.length) {
    params.forEach((el: IParams<D>) => {
      if (!((el.header && el.data) && (el.header.length && el.data.length))) {
        Message.error('导出失败');
        return;
      }
      const worksheetM = workbook.addWorksheet(el.sheetName, { properties: { tabColor: { argb: 'FFC0000' } } });
      // 生成 columns
      const columnsM = el.header.map((col: IHeader): { name: string } => ({ name: col.v }));
      // 生成 rows
      const rowsM = el.data.map((row: D): D[] => {
        return el.header.map(itm => isNull(row[itm.k]) ? row[itm.k] : '');
      });
      // 添加背景图片
      worksheetM.addBackgroundImage(imageId1);
      // 添加数据
      worksheetM.addTable({
        name: el.sheetName,
        ref: 'A1',// 表格左上角位置
        columns: columnsM,
        rows: rowsM
      });
    })
  }

  workbook.xlsx.writeBuffer().then((res) => {
    saveAs(new Blob([res], { type: 'application/octet-stream' }), filename)
  });
  Message.success('导出成功');
};
/**
 * 判断该数据是否为空
 * @param data 要判断的数据
 * @returns 布尔值:true/false
 */
const isNull = (data: any): boolean => {
  return (data ?? '') !== '';
}

/**
 * 绘画水印
 * @param str 要做出水印的文字
 * @returns Base64
 */
const setWatermark = (str: string): string => {
  let id = '1.23452384164.123412416';

  if (document.getElementById(id) !== null) {
    document.body.removeChild(document.getElementById(id) as any);
  }
  // 创建一个画布
  let can = document.createElement('canvas');
  // 设置画布的长宽
  can.width = 500;
  can.height = 420;
  let cans = can.getContext('2d') as any;
  // 旋转角度
  cans.rotate(-25 * Math.PI / 180);
  // 设置字体大小
  cans.font = "800 40px Microsoft JhengHei";
  // 设置填充绘画的颜色、渐变或者模式
  cans.fillStyle = "rgba(130, 142, 162, 0.2)";
  // 设置文本内容的当前对齐方式
  cans.textAlign = 'center';
  // 设置在绘制文本时使用的当前文本基线
  cans.textBaseline = 'Middle';
  cans.fillText(str, 180, 350);

  const dataURL = can.toDataURL('image/png');
  return dataURL;
}

1.页面结构搭建: 首页:设计一个简洁的导航栏,包含 “录入试题”“管理试题”“导出试题” 等主要功能入口。 录入试题页面: 1.使用 Vue.js 的组件化思想,为每种题型(单选题、判断题、填空题、编程题、简答题)创建单独的录入单组件。例如,单选题单包含题目内容输入框、多个选项输入框、正确答案选择框、答案解析输入框等。 2.单使用 Element - UI 的单组件进行布局样式设计,确保输入框、选择框等元素排列整齐,具有良好的视觉效果。并且为每个输入框添加必要的单验证,如题目内容不能为空、单选题选项至少有两个等。 管理试题页面: 1.设计一个格,展示所有已录入试题的关键信息,如题型、题目内容、创建时间等。使用 Element - UI 的格组件实现,该组件支持排序、筛选等功能,方便用户查找特定试题。 2.为每一行数据添加操作按钮,包括 “查看详情”“编辑”“删除”。点击 “查看详情” 按钮弹出对话框,展示该试题的完整信息,包括所有选项、正确答案、答案解析等;“编辑” 按钮则跳转到对应的录入单页面,并预先填充好该试题的已有数据,方便用户修改;“删除” 按钮点击后弹出确认框,确认后从数据库中删除该试题(这里只是前端触发删除操作,实际删除需与后端交互,后续前后端集成时实现)。 导出试题页面: 1.创建一个简单的页面,包含导出格式选择(Word Excel)以及导出范围选择(全部试题或自定义筛选条件后的试题)的功能。提供一个按钮,点击后根据用户选择的格式范围进行试题导出。 2.交互逻辑实现: 录入功能:用户在录入单中输入数据并点击 “提交” 按钮后,使用 JavaScript 收集单数据,进行前端验证(如格式是否正确、必填项是否填写等)。验证通过后,将数据以合适的格式(如 JSON)暂存(实际发送到后端保存将在前后端集成时完成),并弹出提示框告知用户录入成功。 增删查改功能: 1.查询:在管理试题页面的格上方添加搜索框,用户输入关键词后,通过 JavaScript 过滤格数据,实时展示符合条件的试题。同时,利用格自的排序筛选功能,实现多条件查询。 2.新增:点击 “录入试题” 导航进入录入页面,用户录入数据提交后,在管理试题页面的格中实时更新显示新录入的试题(模拟数据更新,实际更新需与后端交互)。 3.修改:用户在编辑页面修改数据并提交后,同样在管理试题页面实时更新该试题的显示信息(模拟数据更新)。 4.删除:点击 “删除” 按钮并确认后,从管理试题页面的格中移除该试题记录(模拟数据删除)。 导出功能: 1.Excel 导出:用户在导出试题页面选择 Excel 格式并点击导出按钮后,使用 XLSX.js 库将暂存的试题数据(或从后端获取的最新数据,前后端集成后实现)转换为 Excel 文件格式,并触发浏览器下载。 2.Word 导出:选择 Word 格式并点击导出按钮后,利用 Docxtemplater 库结合预先设计好的 Word 模板,将试题数据填充到模板中生成 Word 文件。通过调用 Pandoc 工具将生成的临时文件转换为最终的 Word 文件,并触发浏览器下载。
最新发布
04-03
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值