gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網
最全最豐富的資訊網站

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

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

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

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

依賴

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

說明,因為docx繪圖只支持文件流,所以要把網絡文件下載到本地轉成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[] }  // 所有數據 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)    // 比較粗糙的控制單元格長度邏輯   const longHeaders = ['身份證號', '備注']    // 下載遠程資源到本地   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       }     }   }    // 需要多個文件合一   const sections = groupNames.map(groupName => {     const info = data[groupName]     const { institution, leader, phone, coach, doctor, players } = info     // 標頭內容     // let headers = ['序號', '照片', '姓名', '性別', '出生年月', '體重', '級別', '備注']     let headers = ['序號', '照片', '姓名', '性別', '身份證號', '級別', '備注']      // 表格數據     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: {             // 設置寬度 dxa長度單位 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({                     // 將圖片轉化為buffer                     data: fs.readFileSync(cell),                     transformation: {                       width: 100,                       height: 129,                     },                   })                 ]               })]:             [new Paragraph({               alignment: AlignmentType.CENTER,               children:[                 new TextRun(cell || '')               ]             })]           })         })       })     })      // 渲染報名表格     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: `自 由 搏 擊 比 賽 報 名 表(${groupName === Gender.Male ? '男子' : '女子'})`,           heading: HeadingLevel.TITLE,           alignment: AlignmentType.CENTER         }),          // 隊伍信息         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(`  領隊: `),                 ],               }),               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(`  聯系電話: `),                 ],               }),               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(`  隊醫: `),                 ],               }),               new TableCell({                 width: {                   size: 1300,                   type: WidthType.DXA,                 },                 borders: noBoder,                 children: [                   new Paragraph(`${doctor}`)                 ],               }),             ],           }),           ]         }),          // 用于段落距離(table無法設置spacing屬性)         new Paragraph({           spacing: {             // 通過調整before值來調整段落漸進             before: 400,           },           text: ``,         }),          // 選手信息         table,          // 印章和時間         new Paragraph({           style: "wellSpaced",           children: [             new TextRun({               text: 'tttt報名單位章:tttttt',             }),             new TextRun({               text: '年tt'             }),             new TextRun({               text: '月tt'             }),             new TextRun({               text: '日'             })           ]         })       ]     }   })    // 創建整個文檔   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: '江蘇省南京市舜禹集團總部',   leader: '王猛(男)',   phone: '18861856665',   coach: '劉國梁(男)',   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)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
国内少妇毛片视频| 日本成人黄色网| 无套内谢丰满少妇中文字幕| 国产视频九色蝌蚪| 97碰在线视频| 丁香六月激情网| 精品无码国产一区二区三区av| 日韩中文在线字幕| 欧美又粗又长又爽做受| 美女扒开大腿让男人桶| 日本a视频在线观看| heyzo亚洲| 欧美日韩第二页| 天天爽夜夜爽一区二区三区| 四季av一区二区三区| 九九九九九九九九| 性高湖久久久久久久久aaaaa| 亚洲 欧美 综合 另类 中字| 男人日女人逼逼| 超碰在线播放91| 蜜臀在线免费观看| 日本wwww视频| 午夜啪啪小视频| 国产妇女馒头高清泬20p多| 色综合久久久久无码专区| 北条麻妃在线一区| 久久精品国产99久久99久久久| eeuss中文| a在线视频观看| 亚洲制服中文字幕| 成 年 人 黄 色 大 片大 全| 久草综合在线观看| 国产av熟女一区二区三区| 99久久激情视频| 喜爱夜蒲2在线| 538在线视频观看| 成人一区二区av| 手机在线成人免费视频| 妞干网在线观看视频| 国产乱女淫av麻豆国产| 草草久久久无码国产专区| 午夜激情影院在线观看| 青青在线视频免费| 日韩精品在线中文字幕| 亚洲色图欧美自拍| 青青草av网站| 男人靠女人免费视频网站| 日本三日本三级少妇三级66| 日本特黄a级片| 成人亚洲视频在线观看| 黄色片视频在线免费观看| 国产欧美精品aaaaaa片| 国内精品国产三级国产aⅴ久| 最新中文字幕2018| 欧在线一二三四区| 日韩黄色片视频| 91九色在线观看视频| 人妻少妇精品无码专区二区| 91精品国产吴梦梦| 9191国产视频| 99久久免费观看| 国产中文字幕乱人伦在线观看| 午夜久久久久久久久久久| 亚洲男人天堂2021| 国产大尺度在线观看| 玖玖精品在线视频| 毛片在线视频观看| 日本男女交配视频| 欧美亚洲另类色图| 日本成人中文字幕在线| 久久国产这里只有精品| 天堂av2020| 国产又粗又大又爽的视频| 国产激情在线看| 国产精品自拍片| 91淫黄看大片| 亚洲欧美日韩网站| 日本中文字幕一级片| 可以在线看的av网站| 妓院一钑片免看黄大片| 在线视频日韩欧美| 日本福利视频一区| 色哟哟精品视频| 欧美 日韩 国产 在线观看| 4444亚洲人成无码网在线观看| wwwwww欧美| 成人免费无码av| 天堂v在线视频| 男人日女人逼逼| 亚洲第一成肉网| 免费看国产曰批40分钟| 亚洲免费999| 精品视频免费在线播放| 激情视频免费网站| 日本a视频在线观看| 天天色综合社区| 大西瓜av在线| 91亚洲一区二区| 欧美牲交a欧美牲交aⅴ免费下载| 岛国av免费在线| 日本一区二区黄色| 人妻无码一区二区三区四区| 亚洲五月天综合| 大肉大捧一进一出好爽视频| 女同性恋一区二区| 天天爽夜夜爽一区二区三区| 青青草国产精品视频| 樱花草www在线| 国产一伦一伦一伦| 无遮挡又爽又刺激的视频| 成年人深夜视频| 在线播放 亚洲| 亚洲涩涩在线观看| 国产高清视频网站| 97在线免费公开视频| 欧美不卡在线播放| av片在线免费| 99久热在线精品视频| 91香蕉视频免费看| 久久久久久久久久久久91| 国自产拍偷拍精品啪啪一区二区| 97超碰人人爱| 一级黄色片播放| 一级片免费在线观看视频| 午夜国产福利在线观看| 午夜宅男在线视频| www.99av.com| 五月天av在线播放| 国产三级生活片| 欧美激情第四页| 性欧美18一19内谢| 激情五月六月婷婷| 成人免费观看cn| 免费毛片小视频| 无码人妻丰满熟妇区五十路百度| 妺妺窝人体色www在线小说| 免费无码不卡视频在线观看| 丰满爆乳一区二区三区| 99久久久无码国产精品6| 在线免费视频a| 香蕉视频xxxx| 被灌满精子的波多野结衣| 大j8黑人w巨大888a片| 日本精品一区二区三区四区 | 成人在线免费观看网址| 一道本在线观看视频| 日韩成人手机在线| 日韩在线第三页| а 天堂 在线| 欧美国产日韩激情| 99视频在线免费| 亚洲第一天堂久久| 韩国无码av片在线观看网站| 精品欧美一区免费观看α√| 国产又大又黄又粗又爽| 欧美做受777cos| 女性女同性aⅴ免费观女性恋| 91色国产在线| 久操网在线观看| 成人综合久久网| www.99热这里只有精品| 中文字幕第一页在线视频| 国产成人在线小视频| 天天操天天爱天天爽| 97免费视频观看| 岛国av免费在线| 国产97在线 | 亚洲| 亚洲在线观看网站| 91看片就是不一样| 91午夜在线观看| 成人av毛片在线观看| 日本成人在线免费视频| 色一情一乱一乱一区91| 无码人妻精品一区二区三区66| 精品免费久久久久久久| xxww在线观看| 九九热在线免费| 成人在线免费观看av| 成人在线免费观看视频网站| 久久国产精品国产精品| 欧美激情国产精品日韩| 人人妻人人做人人爽| 国产女人18毛片| 国产精品h视频| 99九九99九九九99九他书对| 91av俱乐部| 国产天堂在线播放| 国语对白做受xxxxx在线中国| 日本a视频在线观看| 青青在线视频免费观看| 天天操天天干天天玩| 国产美女视频免费看| www.久久91| 四季av一区二区三区| 午夜精品免费看| 超碰在线资源站| www国产免费| 日本五级黄色片| 日本免费不卡一区二区| 亚洲中文字幕无码专区|