node 生成二维码然后插入word并生成word文档

1,442 阅读2分钟

第一步先生成二维码

  • 考虑到可能数据巨多,需要异步先等图片全部生成完之后再生成word
  • 生成二维码用到的库是 node-qrcode
  • node-qrcode
var QRCode = require('qrcode')
/**
 * CreateQRcode 生成二维码并保存到本地
 * @param {*} item 需要生成二维码的信息
 */
const CreateQRcode = (item , callback)=>{
    QRCode.toFile(path.join(QRcodeOutDir, `${item.****}.png`),`${item.****}`,{margin:6,width:10},function(err){
        if(err){  throw err }
        callback(null)
    })
}
/**
*eachOfLimit(coll, limit, iteratee, callbackopt)
*coll 	        Array | Iterable | AsyncIterable | Object   A collection to iterate over    相当于数据源
*limit          number              The maximum number of async operations at a time     同一批次最多有多少任务在跑
*iteratee       AsyncFunction       An async function (item, key, callback)
*callback       function <optional>
*/
Async.eachLimit(data,10,CreateQRcode,function(err){
    <!--这是回调-->
})})

第二步生成word

  • 生成word用的库 docx
  • docx
const docx = require('docx')
const { AlignmentType, BorderStyle, WidthType, VerticalAlign, Document, Packer, Paragraph, Media, Table, TableCell, TableRow } = docx
    <!--刚进来需要一个doc实例-->
doc = new Document({
    title:'测试文档',
    <!--这是样式,具体可以参考上面的官方文档-->
    styles:{
        paragraphStyles:[
            {
                id:'title',
                paragraph:{
                    alignment:AlignmentType.CENTER
                },
                run:{
                    size:24
                }
            },
            {
                id:"left",
                paragraph: {
                    indent: {
                        left: 1400,
                    },
                },
                run: {
                    size: 20,
                    family:'楷体'
                }
            },
            {
                id:'right',
                paragraph:{
                    indent:{
                        left: 500,
                    }
                },
                run:{
                    size:26
                }
            }
        ]
    }
})

<!--因为需求是生成的table表格,所以以表格为示例-->
<!--这块是生成每一行 tr-->
new TableRow({
    children:[
        new TableCell({
            children:[
                new Paragraph(''),
                new Paragraph({text: `${item.****}`,style:'left'}),
                new Paragraph(''),
                new Paragraph({text:`${item.****}`,style:'left'}),
                new Paragraph(''),
                new Paragraph({text:`${item.****}`,style:'left'}),
                new Paragraph(''),
            ],
            <!--width 下面的 WidthType.PERCENTAGE 是按百分比算-->
            width:{
                size: 54,
                type: WidthType.PERCENTAGE
            },
            borders:{
                right:{style:BorderStyle.NONE,size:0,color:'ffffff'}
            }
        }),
        new TableCell({
            children:[
                new Paragraph(''),
                new Paragraph(Media.addImage(doc,fs.readFileSync(path.join(QRcodeOutDir, `${item.****}.png`)),120,120)),
                <!--这块是插入图片-->
            ],
            <!--width 下面的 WidthType.PERCENTAGE 是按百分比算-->
            width:{
                size: 26,
                type: WidthType.PERCENTAGE
            },
            borders:{
                left:{style:BorderStyle.NONE,size:0,color:'ffffff'},
                right:{style:BorderStyle.NONE,size:0,color:'ffffff'},
            }
        }),
        new TableCell({
            children:[
                new Paragraph({text:'****',style:'right'}),
                new Paragraph(''),
                new Paragraph({text:'****',style:'right'}),
            ],
                <!--width 下面的 WidthType.PERCENTAGE 是按百分比算-->
            width:{
                size: 20,
                type: WidthType.PERCENTAGE
            },
            borders:{
                left:{style:BorderStyle.NONE,size:0,color:'ffffff'}
            },
            verticalAlign:VerticalAlign.CENTER,
        })
    ],
})

<!--可以每生成一条row都放到数组rows里面-->
<!--这块是直接给表格的rows赋值-->
const table = new Table({
    rows:rows
})

doc.addSection({
    children:[
            <!--在这块是word除了table之外还需要什么内容就添加什么内容-->
        new Paragraph({text:'****',style:'title'}),
        table
    ]
})

<!--最后根据输出路径生成word-->
Packer.toBuffer(doc).then((buffer)=>{
    fs.writeFileSync(path.join(wordOutDir, `${wordInfos.taskName}.docx`),buffer)
})
  • fs,path这些库再次就不多说了
  • 当然,生成word文档也是用的eachlimit,这个东西童鞋们可以研究研究
  • 最后,给童鞋们展示一下最终效果,配合着最终效果跟文档,聪明的大家肯定能看懂上面的东西

  • 属于隐私信息,就打码了,打码部分只是文字,大家可以参考
  • 给自己记录一下,同时也希望能帮到有差不多相似需求的童鞋们