index.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. const fs = require('fs')
  2. const path = require('path')
  3. const compressing = require('compressing')
  4. const rimrif = require('rimraf')
  5. const shell = require('shelljs');
  6. const crypto = require('crypto');
  7. /**
  8. * docx 替换模板字符串内容
  9. * @example
  10. // 要替换内容的模板
  11. let inputDocx = 'cs.docx'
  12. // 替换完成的docx文件
  13. let outputDocx = 'dd.docx'
  14. // {{xx}} 处要替换的内容
  15. let replaceData = {
  16. name: '替换name处的内容',
  17. age: '替换age处的内容',
  18. }
  19. replaceDocx(inputDocx, outputDocx, replaceData)
  20. */
  21. function replaceDocx(inputDocxPath, outputDocxPath, options) {
  22. return new Promise((resolve,reject)=>{
  23. // 解压出来的临时目录
  24. let tempDir = path.join(__dirname , "temp")
  25. let md5 = crypto.createHash('md5');
  26. let outmd5 = md5.update(outputDocxPath).digest('hex')
  27. let tempDocxPath = path.join(tempDir , outmd5)
  28. // 要替换的xml文件位置
  29. let tempDocxXMLName = path.join(tempDocxPath,`word/document.xml`)
  30. // 压缩文件夹为文件
  31. let dir_to_docx = (inputFilePath, outputFilePath) => {
  32. outputFilePath = path.join(tempDir,outputFilePath)
  33. // 创建压缩流
  34. let zipStream = new compressing.zip.Stream()
  35. // 写出流
  36. let outStream = fs.createWriteStream(outputFilePath)
  37. fs.readdir(inputFilePath, null, (err, files) => {
  38. if (!err) {
  39. files.map(file => path.join(inputFilePath, file))
  40. .forEach(file => {
  41. zipStream.addEntry(file)
  42. })
  43. }
  44. })
  45. // 写入文件内容
  46. zipStream.pipe(outStream)
  47. .on('close', () => {
  48. // 打包完成后删除临时目录
  49. // console.log(tempDocxPath)
  50. shell.rm("-r",tempDocxPath)
  51. // rimrif.rimrafSync(tempDocxPath)
  52. resolve(true)
  53. })
  54. }
  55. // 替换word/document.xml文件中{{xx}}处的内容
  56. let replaceXML = (data, text) => {
  57. Object.keys(data).forEach(key => {
  58. text = text.replaceAll(`{{${key}}}`, data[key])
  59. })
  60. return text
  61. }
  62. // 解压docx文件替换内容重新打包成docx文件
  63. compressing.zip.uncompress(inputDocxPath, tempDocxPath)
  64. .then(() => {
  65. // 读写要替换内容的xml文件
  66. fs.readFile(tempDocxXMLName, null, (err, data) => {
  67. if (!err) {
  68. let text = data.toString()
  69. text = replaceXML(options, text)
  70. fs.writeFile(tempDocxXMLName, text, (err) => {
  71. if (!err) {
  72. dir_to_docx(tempDocxPath, outputDocxPath)
  73. } else {
  74. reject(err)
  75. }
  76. })
  77. } else {
  78. reject(err)
  79. }
  80. })
  81. }).catch(err => {
  82. reject(err)
  83. })
  84. })
  85. }
  86. module.exports.replaceDocx = replaceDocx