成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長(zhǎng)資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

怎么利用node生成word文檔?使用庫分享

怎么利用node生成word文檔?下面本篇文章給大家介紹一下使用node生成word文檔的方法,分享一個(gè)實(shí)用庫,聊聊該庫的使用方法,希望對(duì)大家有所幫助!

怎么利用node生成word文檔?使用庫分享

最近有項(xiàng)目需要用到生成word文檔,平時(shí)經(jīng)常用的都是通過模板生成,里面變量使用占位符替換,好處是快捷、方便、簡(jiǎn)單、不需要通過代碼調(diào)word樣式,確定是很多庫不支持圖片繪制(很多都是付費(fèi)功能),找一圈,發(fā)現(xiàn)一個(gè)很有意思的庫,正好也滿足我們的需求,特此分享一下

依賴

// https://docx.js.org/#/ npm i docx   // https://www.npmjs.com/package/download npm i download

說明,因?yàn)閐ocx繪圖只支持文件流,所以要把網(wǎng)絡(luò)文件下載到本地轉(zhuǎn)成buffer

代碼

話不多說,上代碼

import * as fs from "fs" import { Document, Packer, Paragraph, TextRun, ImageRun, HeadingLevel, AlignmentType, convertInchesToTwip, Table, TableRow, TableCell, WidthType, VerticalAlign, BorderStyle } from "docx" const download = require('download')  // 性別 enum Gender {   Male = 'male',   Female = 'female' }  // 選手 type PlayerSchema = {   name: string   gender: string   idCard?: string   birthday?: string   weight?: string   remark?: string   avatar?: string   localAvatar?: string   level: string } type GroupSchema = {   // gender: Gender   institution: string   leader: string   phone: string   coach: string   doctor: string   players: PlayerSchema[] }  // 所有數(shù)據(jù) interface DataSchema  {   [key: string]: GroupSchema }  // 表格無邊框 const noBoder = {   top: {     style: BorderStyle.NIL,     size: 0,     color: 'FFFFFF'   },   bottom: {     style: BorderStyle.NIL,     size: 0,     color: 'FFFFFF'   },   left: {     style: BorderStyle.NIL,     size: 0,     color: 'FFFFFF'   },   right: {     style: BorderStyle.NIL,     size: 0,     color: 'FFFFFF'   } }  // 刪除下載的照片及文件夾 function delStaticFile(groupNames: string[]) {   for (let groupName of groupNames) {     if (fs.existsSync(groupName)) {       const files = fs.readdirSync(groupName)       files.map((file: string) => {         let curPath = groupName + "/" + file         // 刪除選手招聘         fs.unlinkSync(curPath)       })       fs.rmdirSync(groupName)     }   } }  // 生成word async function generate (data: DataSchema) {   const groupNames = Object.keys(data)    // 比較粗糙的控制單元格長(zhǎng)度邏輯   const longHeaders = ['身份證號(hào)', '備注']    // 下載遠(yuǎn)程資源到本地   for (let groupName of groupNames) {     if (!fs.existsSync(groupName)) {       fs.mkdirSync(groupName)     }      const players = data[groupName].players     for (let player of players) {       if (player.avatar) {         const avatarArr = player.avatar.split('/')         const fileName = `${groupName}/${avatarArr[avatarArr.length - 1]}`          if (!fs.existsSync(fileName)) {           await download(player.avatar, groupName)         }         // 下載后的本地的資源路徑         player.localAvatar = fileName       }     }   }    // 需要多個(gè)文件合一   const sections = groupNames.map(groupName => {     const info = data[groupName]     const { institution, leader, phone, coach, doctor, players } = info     // 標(biāo)頭內(nèi)容     // let headers = ['序號(hào)', '照片', '姓名', '性別', '出生年月', '體重', '級(jí)別', '備注']     let headers = ['序號(hào)', '照片', '姓名', '性別', '身份證號(hào)', '級(jí)別', '備注']      // 表格數(shù)據(jù)     let tableData: any[][] = []     tableData.push(headers)      // 填充選手信息     let index = 1     for (let player of players) {       tableData.push([         index.toString(),         player.localAvatar || '',         player.name,         player.gender === Gender.Male ? '男' : '女',         player.idCard,         // player.birthday,         // player.weight,         player.level,         player.remark,       ])       index++     }      // 表格渲染     const tableRows = tableData.map(colums => {       return new TableRow({         children: colums.map(cell => {         return new TableCell({           verticalAlign: VerticalAlign.CENTER,           width: {             // 設(shè)置寬度 dxa長(zhǎng)度單位 https://stackoverflow.com/questions/14360183/default-wordml-unit-measurement-pixel-or-point-or-inches             size: longHeaders.some(j => cell === j) ? 3000 : 800,             type: WidthType.DXA,           },           children: cell && colums.findIndex(i => i === cell) === 1 && cell !== '照片' ?               [new Paragraph({                 alignment: AlignmentType.CENTER,                 children: [                   new ImageRun({                     // 將圖片轉(zhuǎn)化為buffer                     data: fs.readFileSync(cell),                     transformation: {                       width: 100,                       height: 129,                     },                   })                 ]               })]:             [new Paragraph({               alignment: AlignmentType.CENTER,               children:[                 new TextRun(cell || '')               ]             })]           })         })       })     })      // 渲染報(bào)名表格     const table = new Table({       alignment: AlignmentType.CENTER,       rows: tableRows     })      return {       properties: {},       children: [         // new Paragraph({         //   style: "wellSpaced",         //   children: [         //     new TextRun({         //       text: '附件 4',         //       color: '999999',         //     })         //   ],         // }),          // 表頭信息         new Paragraph({           spacing: {             before: 400,             after: 400           },           style: "Title",           text: `自 由 搏 擊 比 賽 報(bào) 名 表(${groupName === Gender.Male ? '男子' : '女子'})`,           heading: HeadingLevel.TITLE,           alignment: AlignmentType.CENTER         }),          // 隊(duì)伍信息         new Table({           style: "wellSpaced",           alignment: AlignmentType.CENTER,           borders: noBoder,           rows: [             new TableRow({             children: [               new TableCell({                 width: {                   size: 600,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`單位: `),                 ],               }),               new TableCell({                 width: {                   size: 1800,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`${institution}`)                 ],               }),               new TableCell({                 width: {                   size: 700,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`  領(lǐng)隊(duì): `),                 ],               }),               new TableCell({                 width: {                   size: 1200,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`${leader}`)                 ],               }),               new TableCell({                 width: {                   size: 1100,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`  聯(lián)系電話: `),                 ],               }),               new TableCell({                 width: {                   size: 1400,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`${phone}`)                 ],               }),               new TableCell({                 width: {                   size: 700,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`  教練: `),                 ],               }),               new TableCell({                 width: {                   size: 1300,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`${coach}`)                 ],               }),               new TableCell({                 width: {                   size: 700,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`  隊(duì)醫(yī): `),                 ],               }),               new TableCell({                 width: {                   size: 1300,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`${doctor}`)                 ],               }),             ],           }),           ]         }),          // 用于段落距離(table無法設(shè)置spacing屬性)         new Paragraph({           spacing: {             // 通過調(diào)整before值來調(diào)整段落漸進(jìn)             before: 400,           },           text: ``,         }),          // 選手信息         table,          // 印章和時(shí)間         new Paragraph({           style: "wellSpaced",           children: [             new TextRun({               text: 'tttt報(bào)名單位章:tttttt',             }),             new TextRun({               text: '年tt'             }),             new TextRun({               text: '月tt'             }),             new TextRun({               text: '日'             })           ]         })       ]     }   })    // 創(chuàng)建整個(gè)文檔   const doc = new Document({     styles: {       paragraphStyles: [         {           id: "Title",           name: "title",           basedOn: "Normal",           next: "Normal",           quickFormat: true,           run: {               size: 30,               bold: true,               color: "000000"           }         },         {           id: "wellSpaced",           name: "Well Spaced",           basedOn: "Normal",           quickFormat: true,           paragraph: {             indent: {               left: convertInchesToTwip(0.5),             },             spacing: {               before: 400,             },           },         },       ],     },     sections   })      // 生成word文檔   Packer.toBuffer(doc).then((buffer) => {     fs.writeFileSync("enrolls.docx", buffer)   })    // 刪除下載的選手照片   delStaticFile(groupNames) }  const group: GroupSchema = {   institution: '江蘇省南京市舜禹集團(tuán)總部',   leader: '王猛(男)',   phone: '18861856665',   coach: '劉國(guó)梁(男)',   doctor: '楊永信(女)',   players: [     {       name: '萊昂納多迪卡普里奧',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/13.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/7.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       idCard: '320888199001019878',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     },     {       name: '張三',       gender: Gender.Male,       idCard: '320888199001019878',       birthday: '1999-01-02',       weight: '60kg',       avatar: 'https://multi-xm.oss-cn-hangzhou.aliyuncs.com/atms/14.png',       remark: '',       level: '60kg'     }   ] }  const data: DataSchema = {   [Gender.Male]: group,   [Gender.Female]: group, }  generate(data)

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
日日噜噜夜夜狠狠久久丁香五月 | 顶级欧美熟妇高潮XXXXX| 把腿张开让老子臊烂你的视频| 超碰色偷偷男人的天堂| 国产成人亚洲精品无码车A| 国产无遮挡又黄又爽不要VIP网| 激情偷乱人伦小说免费看| 久久久久亚洲AV无码专区导航| 免费人成在线观看| 人妻无奈被迫屈辱1-9| 少妇寂寞难耐被黑人中出| 亚洲AV成人精品日韩一区麻豆| 亚洲欧洲日产V一个人免费观看视频WWW高清 | 亚洲AV无码成人精品区在线播放| 亚洲综合激情七月婷婷| JAPONENSIS性护士| 国产AV永久精品无码| 精品久久久久久天美传媒 | 色婷婷五月综合亚洲小说| 无码高潮爽到爆的喷水视频| 亚洲国产精品久久久久秋霞1| 在线中文新版最新版在线| 按摩师的巨大滑进我的身体| 国产精品美女久久久浪潮AV| 久久精品99国产精品蜜桃| 欧美牲交视频免费观看| 无码精品人成人片在线观看| 亚洲综合无码AV一区二区| 锕锕锕锕锕锕锕轻点好痛免费| 国产精品扒开腿做爽爽爽| 久久久精品人妻人人澡| 欧美一区二区三区放荡人妇| 无遮挡又黄又刺激的视频| 亚洲最大的成人网站| 成人AV无码乱码在线观看无码| 国精产品W灬源码1688伊| 末发育娇小性色XXXXX| 特大巨黑吊XXXX高潮| 亚洲午夜成人AV电影| 插插射啊爱视频日A级| 护士交换粗吟配乱大交| 欧美丰满熟妇性XXXX| 午夜影视免费观看2023| 91久久精品www人人做人人爽| 国产成人精品亚洲日本专区61 | 人妻少妇啊灬啊灬用力啊快| 性做久久久久久久| 996久久国产精品线观看| 国产日产欧美一区二区蜜桃| 免费看高清大片的APP在线看| 玩弄丰满少妇XXXXX| 中文字幕人妻无码一区二区三区 | 99精品一区二区三区无码吞精 | 小SAO货CAO得你舒服吗男男| 18禁止免费观看试看免费大片| 国产精品久久午夜夜伦鲁鲁 | 影音先锋亚洲AV少妇熟女| 国产AⅤ无码久久丝袜美腿| 巨爆乳中文字幕巨爆区巨爆乳无码| 少妇又粗又大人妻无码| 中国老熟女重囗味HDXX| 国产精品久久一国产精品胖虎 | 最新亚洲人成网站在线观看| 国产农村乱人伦精品视频| 欧美日韩一区二区成人午夜电影| 亚洲AV之男人的天堂| 边做边爱完整版免费视频播放百度| 久久AV伊人蜜臀一区二区| 试看120秒男女啪啪免费| 中文无码AV电影在线观看网站| 国产乱人伦AV麻豆网| 欧美一区二区在线视频| 亚洲人成无码网站久久99热国产| 丁香色婷婷国产精品视频 | 中文字幕一区二区三区乱码 | 免费人成在线观看视频无码| 亚洲AV日韩AV无码污污网站| 从后面糟蹋成功视频| 麻花传媒剧国产MV入口在线观看| 亚洲AV老熟妇在线观看| 粗大黑人巨茎大战欧美成人| 男人J进女人屁网站免费| 亚洲乱码日产精品BD在线看| 国产精品高清一区二区三区人妖| 屁屁草草影院CCYYCOM| 亚洲中文字幕无码中文| 国产无遮挡18禁无码网站| 色婷婷五月综合激情中文字幕| 99久久国产综合精麻豆| 久久精品亚洲中文无东京热| 亚洲AV高清在线观看一区二区三| 国产AⅤ精品一区二区三区久久| 欧美一性一乱一交一视频C| 一区二区三区乱码在线 | 中文| 国产毛片一区二区精品| 少妇白浆高潮无码免费区| av资源在线观看少妇| 老师的粉嫩小又紧水又多| 亚洲精品卡一卡2卡3卡4卡| 国产口爆吞精在线视频| 上边一面亲下边一面膜的作用| CHINESE中国丰满熟妇| 噜噜狠狠色综合久色AⅤ五区| 亚洲人成电影在线观看天堂色| 国产一区二区三区影院| 玩乡下黄花小处雏女| 房东老头揉捏吃我奶头影片| 全彩十八禁漫画无遮挡| 97精品国产手机| 美女MM131爽爽爽| 一本之道AV不卡精品| 久久97精品久久久久久久不卡 | 18禁黄网站禁片免费观看香港| 久久久久久精品人妻免费网站| 亚洲欧洲日产国码AⅤ | 国产欧美日韩专区发布| 我的好妈妈中文字幕| 国99精品无码一区二区三区| 日韩一卡2卡3卡4卡| 成人亚洲区无码区在线点播| 日本熟妇JAPANESE丰满| 边做饭边被躁BD苍井空小说| 人妻办公室出轨上司HD院线| WWW.色五月.COM| 人扒开女人添高潮的视频嗯啊| ALEXAGRACE大战黑人| 欧美日韩精品SUV| CHINA真实VIDEOS另类| 破外女出血视频全过程| 啊灬啊灬啊灬快灬深高潮了亚洲乱色视频在线观看 | 国产精品呻吟AV久久高潮| 午夜A级成人免费毛片| 国产丝袜无码一区二区三区视频| 小SAO货撅起屁股扒开GIF动| 国产亚洲精品A在线无码| 亚洲AV婷婷五月产AV中文| 国产在线精品成人一区二区三区| 亚洲AV永久无码精品秋霞电影影 | 女人裸体张开腿无遮挡| A级毛片无码免费真人久久| 欧洲码和亚洲码的尺码区别| 边做边爱完整版免费视频播放| 色优久久久久综合网鬼色| 国产成人亚洲精品无码车A| 小S货又想挨C了叫大声点| 国产一区二区三区在线电影| 亚洲精品AⅤ无码精品丝袜足| 久久精品日日躁夜夜躁| 稚嫩奶罩伸进揉捏H| 欧美日韩精品一区二区在线播放 | 暴力调教一区二区三区| 日老太太毛茸茸B.内射| 国产精品白丝JK白祙喷水视频| 亚洲AⅤ天堂AV天堂无码麻豆| 精品人妻码一区二区三区| 又粗又硬又大又爽免费视频播放| 免费无遮挡又黄又爽网站 | 搡老女人老91妇女老熟女oo| 国产成人综合精品无码| 亚洲AV无码麻豆一区二区三区| 久久精品国产亚洲AV香蕉| 18禁又污又黄又爽的网站不卡| 日本亚洲色大成网站WWW| 国产精品V无码A片在线看| 亚洲成A人一区二区三区| 狂猛欧美激情性XXXX大豆行情| JAPANESE中国丰满少妇| 天空影院手机免费观看在线| 狠狠躁夜夜躁人人爽天天5| 影音先锋AⅤ无码资源网| 人妻无奈被迫屈辱1-9| 国产精品香港三级国产AV| 亚洲日韩精品欧美一区二区一| 女儿的朋友中字头| 国产AⅤ无码一区二区三区| 亚洲AV无码国产永久播放蜜芽 | 日韩精品一区二区三区中文无码| 国产精品夜间视频香蕉| 艳妇乳肉豪妇荡乳AV| 人与禽交VIDEOSGRATI| 国产亚洲精品A在线观看| 在线精品国精品国产尤物| 日韩AV一区二区三区| 国内外精品激情刺激在线| 装睡被陌生人摸出水好爽| 色欲精品国产一区二区三区AV| 精品国产AⅤ一区二区三区V免费| 2021自拍偷在线精品自拍偷 | 国产成人A区在线观看| 亚洲日韩国产精品第一页一区| 欧美巨大XXXX做受| 国产精品IGAO视频网| 一区二区三区国产精华护肤品 | 顶级RAPPER潮水日本| 亚洲精品国产一区二区三区在线观 | 一区二区三区av在线| 上面一个摸下面一个手念什么| 精品久久久久久中文字幕| 宝宝好大我都握不住了视频| 亚洲ΑV久久久噜噜噜噜噜|