亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何利用node生成word文檔

發布時間:2022-07-29 09:37:31 來源:億速云 閱讀:141 作者:iii 欄目:web開發

這篇“如何利用node生成word文檔”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“如何利用node生成word文檔”文章吧。

如何利用node生成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: '\t\t\t\t報名單位章:\t\t\t\t\t\t',
            }),
            new TextRun({
              text: '年\t\t'
            }),
            new TextRun({
              text: '月\t\t'
            }),
            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)

以上就是關于“如何利用node生成word文檔”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

台东县| 晋城| 宝应县| 内江市| 松滋市| 老河口市| 郸城县| 尉氏县| 和林格尔县| 墨江| 若尔盖县| 延津县| 融水| 德州市| 河津市| 洪江市| 清苑县| 枣庄市| 陆河县| 靖远县| 南充市| 永平县| 沙河市| 铜陵市| 夏邑县| 海口市| 禹城市| 奉化市| 和顺县| 台湾省| 青神县| 平原县| 明光市| 西城区| 黄龙县| 绵阳市| 桐乡市| 岗巴县| 钟祥市| 昌吉市| 临沭县|