zoukankan      html  css  js  c++  java
  • nodejs生成导出word

    导出word的功能,目前看了两个模块:officegen 和 docxtemplater

    officegen是自己绘制word格式: https://github.com/Ziv-Barber/officegen

    docxtemplater以模板替换的模式 : https://docxtemplater.readthedocs.io/en/latest/installation.html

    officegen操作

    1. 安装

    npm install officegen

    2. 使用

    import * as officegen from 'officegen'
    import { createWriteStream } from 'fs'
    import { Request, Response } from 'express';
    
    export function createWord(req: Request, res: Response) {
    
      const docx = officegen('docx')
      docx.on('finalize', function (written) {
        console.log('word创建完成.')
      })
      docx.on('error', function (err) {
        console.log(err)
      })
      // Create a new paragraph: 
      /*
      addText(内容, {
        color: 字体颜色string,
        back: 后背景颜色string,
        bold: 加粗 boolean,默认是false
        underline:下划线默认false,
        highlight: 提亮,默认黄色,
        link: 添加一个链接
        align: 位置, center/right
      })
      */
      let pObj = docx.createP()
      pObj.addText('Simple')
      pObj.addText(' with color', { color: '000088' })
      pObj.addText(' and back color.', { color: '00ffff', back: '000088' })
    
      pObj = docx.createP()
    
      pObj.addText('Since ')
      pObj.addText('officegen 0.2.12', {
        back: '00ffff',
        shdType: 'pct12',
        shdColor: 'ff0000'
      })
    
      // Use pattern in the background.
      pObj.addText(' you can do ')
      pObj.addText('高亮 ', { highlight: true }) // Highlight!
      pObj.addText('填充!', { highlight: 'darkGreen' }) // Different highlight color.
    
      pObj = docx.createP()
      // 添加一个链接
      pObj.addText('这是一个链接 ')
      pObj.addText('点我', { underline: true, color: '000088', link: 'https://github.com' })
      pObj.addText('!')
    
      pObj = docx.createP()
      pObj.addText('加粗—+下划线', { bold: true, underline: true })
    
      pObj = docx.createP({ align: 'center' })
    
      pObj.addText('加边框', {
        border: 'dotted',
        borderSize: 12,
        borderColor: '88CCFF'
      })
    
      pObj = docx.createP()
      pObj.options.align = 'right'
    
      pObj.addText('Align this text to the right.')
    
      pObj = docx.createP()
    
      pObj.addText('Those two lines are in the same paragraph,')
      pObj.addLineBreak()// 换行
      pObj.addText('but they are separated by a line break.')
    
      docx.putPageBreak()//换页
    
      pObj = docx.createP()
    
      pObj.addText('Fonts face only.', { font_face: 'Arial' })
      pObj.addText(' 换字体并加大.', { font_face: 'Arial', font_size: 40 })
    
      pObj = docx.createP({align: 'center'})
      // pObj.options.align = 'center'
      pObj.addText('学生信息', { bold: true, font_face: 'Arial', font_size: 18 })
      let tableStyle = {
        tableColWidth: 2400,
        tableSize: 24,
        tableColor: "ada",
        tableAlign: "center",
        tableVAlign: "center",
        tableFontFamily: "Comic Sans MS",
        borders: true
      }
      let table: any = [
        [{
          val: '姓名',
          opts: {
            align: "center",
            vAlign: "center",
            sz: '36',
            // cellColWidth: 42,
            // b: true,
            // shd: {
            //   fill: "7F7F7F",
            //   themeFill: "text1",
            //   "themeFillTint": "80"
            // },
            // fontFamily: "Avenir Book"
          }
        }, {
          val: '性别',
          opts: {
            align: "center",
            vAlign: "center",
            sz: '36',
          }
        }, {
          val: '年龄',
          opts: {
            align: "center",
            vAlign: "center",
            sz: '36',
          }
        }]
      ]
    
      let student1 = ['李四', '男', 12]
      let student2 = ['李四2', '男', 28]
      table.push(student1, student2)
      // 表格
      docx.createTable(table, tableStyle)
    
      docx.putPageBreak()
    
      pObj = docx.createP()
    
      // 添加图片
      pObj.addImage('dd.jpg')
    
    
    /* 服务器生成文件
      let out = createWriteStream('example.docx')
    
      out.on('error', function (err) {
        console.log(err)
      })
    
      // Async call to generate the output file:
      docx.generate(out) 
    */
      // 返回给前端,前端直接下载
      res.writeHead(200, {
        // 注意这里的type设置,导出不同文件type值不同application/vnd.openxmlformats-officedocument.wordprocessingml.document
        "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        'Content-disposition': 'attachment; filename=out-' + new Date().getTime() + '.docx'
      });
      docx.generate(res)
    } 

    docxtemplater操作,图片替换是需要收费的

    1. 安装

    npm install docxtemplater pizzip

    2. 使用

    var PizZip = require('pizzip');
    var Docxtemplater = require('docxtemplater');
    import { Request, Response } from 'express';
    
    var fs = require('fs');
    var path = require('path');
    
    // The error object contains additional information when logged with JSON.stringify (it contains a properties object containing all suberrors).
    function replaceErrors(key, value) {
      if (value instanceof Error) {
        return Object.getOwnPropertyNames(value).reduce(function (error, key) {
          error[key] = value[key];
          return error;
        }, {});
      }
      return value;
    }
    
    function errorHandler(error) {
      console.log(JSON.stringify({ error: error }, replaceErrors));
    
      if (error.properties && error.properties.errors instanceof Array) {
        const errorMessages = error.properties.errors.map(function (error) {
          return error.properties.explanation;
        }).join("
    ");
        console.log('errorMessages', errorMessages);
      }
      throw error;
    }
    
    export function paddingWord(req: Request, res: Response) {
    
      console.log( path.resolve( __dirname, '../input.docx'), )
    
      // 读取模板 加载的docx文件为二进制
      var content = fs
        .readFileSync(path.resolve(__dirname, '../src/input.docx'), 'binary');
    
      var zip = new PizZip(content);
      var doc;
      try {
        doc = new Docxtemplater(zip);
      } catch (error) {
        // Catch compilation errors (errors caused by the compilation of the template : misplaced tags)
        errorHandler(error);
      }
    
      //set the templateVariables
      doc.setData({
        first_name: 'John',
        last_name: 'Doe',
        phone: '0652455478',
        description: 'New Website。。。'
      });
    
      try {
       doc.render() // 匹配
      }
      catch (error) {
        errorHandler(error);
      }
      // 生成二进制流
      var buf = doc.getZip().generate({ type: 'nodebuffer' });
      res.writeHead(200, {
        "Content-Type": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
        'Content-disposition': `attachment; filename= ${new Date().getTime()}.docx`
    });
    
      res.end(buf)
      // buf is a nodejs buffer, you can either write it to a file or do anything else with it.
      // fs.writeFileSync(path.resolve(__dirname, 'output.docx'), buf);
    }
  • 相关阅读:
    51Nod 1016 水仙花数 V2(组合数学,枚举打表法)
    April Fools Contest 2017 题解&源码(A,数学 B,数学 C,数学 D,字符串 E,数字逻辑 F,排序,卡时间,G,数学)
    统计0到n之间1的个数[数学,动态规划dp](经典,详解)
    hihoCoder #1082 : 然而沼跃鱼早就看穿了一切(字符串处理)
    洛谷 P1876 开灯(思维,枚举,规律题)
    Codeforces 789A Anastasia and pebbles(数学,思维题)
    51Nod 1182 完美字符串(字符串处理 贪心 Facebook Hacker Cup选拔)
    机器学习(Machine Learning)&深度学习(Deep Learning)资料
    看一下你在中国属于哪个阶层?
    python读取mnist
  • 原文地址:https://www.cnblogs.com/liangyy/p/12466111.html
Copyright © 2011-2022 走看看