【Vue項(xiàng)目】使用 xlsx-template 在xlsx文件內(nèi)實(shí)現(xiàn)占位符替換

為什么有這種需求

有時(shí)候我們需要在網(wǎng)頁進(jìn)行 office 文本編輯,但是 office 文件的編輯選項(xiàng)過多且不開源,一定需要集成其它在線編輯方案才可以,比如金山文檔的在線協(xié)作方案
但是有時(shí)候我們并不需要如此健壯的成熟方案,很多時(shí)候我們對(duì)一個(gè)現(xiàn)在 office 模版只需要修改其中幾項(xiàng)的文字就可以了。這種情況下,我們只需要寫一個(gè)現(xiàn)成的表單,像問卷一樣填寫相關(guān)內(nèi)容,把填寫的內(nèi)容再轉(zhuǎn)入到 office 文件中就可以了。

模版文件.png

如上,現(xiàn)在我希望用戶在我的網(wǎng)頁上只填寫 name 與 id
之后網(wǎng)頁會(huì)將 xlsx 文件中對(duì)應(yīng)占位符替換成用戶填寫的對(duì)應(yīng)內(nèi)容,這個(gè)需求可以通過 xlsx-template 來實(shí)現(xiàn)

項(xiàng)目版本

測(cè)試項(xiàng)目為Vue項(xiàng)目,Vue版本為3,webpack版本為5(重點(diǎn),xlsx-template庫與這個(gè)版本有沖突,后面講解決方案),包管理器為 yarn(npm也可以),測(cè)試文件類型為 typeScript(使用javaScript也可以,稍作修改即可)

代碼

安裝 xlsx-template: 
npm i xlsx-template 或 yarn add xlsx-template
安裝 jszip-utils: 
npm i jszip-utils 或 yarn add jszip-utils
安裝 file-saver: 
npm i file-saver 或 yarn add file-saver

// @ts-ignore
import JSZipUtils from 'jszip-utils'
import {saveAs} from 'file-saver'
執(zhí)行代碼:
const XlsxTemplate = require('xlsx-template');
JSZipUtils.getBinaryContent('/xlsx/template1.xlsx',(err: any, data: Buffer) => {
const template = new XlsxTemplate(data);

// Replacements take place on first sheet
const sheetNumber = 1;

// Set up some placeholder values matching the placeholders in the template
const values = {
    name: '人人人',
    id: 888888
};

// Perform substitution
template.substitute(sheetNumber, values);

// Get binary data
let templateData = template.generate({type: 'blob'});
    saveAs(templateData, 'new.xlsx')
})
vue.config.js 設(shè)置

const {defineConfig} = require('@vue/cli-service')
const webpack = require('webpack')

module.exports = defineConfig({
    lintOnSave: false,
    transpileDependencies: true,
    configureWebpack: {
        plugins: [
            new webpack.ProvidePlugin({
                process: 'process/browser',
                Buffer: ['buffer', 'Buffer']
            })
        ],
        resolve: {
            fallback: {
                "path": require.resolve('path-browserify'),
                "util": require.resolve("util/"),
                "stream": require.resolve("stream-browserify"),
                "constants": require.resolve("constants-browserify"),
                "assert": require.resolve("assert/"),
                "fs": false,
            }
        }
    }
})

注意:上文中類似庫名的地方,除了fs和buffer外都需要使用 npm 或 yarn 安裝對(duì)應(yīng)的庫
比如:npm i util 與 yarn add assert
需要加載的庫名如下:
webpack  process  path-browserify  util  stream-browserify  constants-browserify  assert

vue.config.js 講解

因?yàn)?xlsx-template 庫是在 webpack4 的基礎(chǔ)上打包的,在 webpack5 的項(xiàng)目上出現(xiàn)在非常多的錯(cuò)誤,故需要如上 vue.config.js 的設(shè)置。
上面的設(shè)置雖少,但是解決了至少4個(gè)類型的錯(cuò)誤,共數(shù)十個(gè)具體錯(cuò)誤

  1. Can't resolve 'fs' 問題
    這個(gè)問題其實(shí)是因?yàn)?fs 庫已經(jīng)無法直接調(diào)用,而在 xlsx-template 代碼卻有調(diào)用
    使用 resolve.fallback: { fs: false } 可以跳過編譯檢測(cè)
Can't resolve 'fs'

解決自:https://github.com/webpack-contrib/css-loader/issues/447#issuecomment-761853289

  1. process is not defined 問題
    這個(gè)問題可能是因?yàn)樵?webpack5 中 process 已經(jīng)無法在項(xiàng)目獲取,需要使用外部引用并轉(zhuǎn)換成同名引用
    使用 new webpack.ProvidePlugin({ process: 'process/browser' }) 可以解決
process is not defined

解決自:https://stackoverflow.com/questions/41359504/webpack-bundle-js-uncaught-referenceerror-process-is-not-defined

  1. 各種 webpack < 5 開頭的問題
    這種問題在控制臺(tái)已經(jīng)說明了解決方法,只是可能很多人不知道具體應(yīng)該把解決代碼寫在哪里,上圖中的 resolve.fallback: { ... } 中除了 fs:false 其它都是會(huì)出現(xiàn)問題的部分的解決方法
    這個(gè)問題仍然是 webpack 版本造成的,但是不能像 fs 一樣忽略,必須注入
webpack < 5 開頭的問題之一

解決自:https://stackoverflow.com/questions/64557638/how-to-polyfill-node-core-modules-in-webpack-5

  1. Cannot read properties of undefined (reading 'filename') 或 buffer 問題
    在vue3項(xiàng)目上會(huì)報(bào) “Cannot read properties of undefined”,但是在我的另一個(gè)vue2項(xiàng)目中會(huì)直接報(bào)找不到 buffer 函數(shù)問題,所以這是個(gè)無法調(diào)用到 buffer api 的問題
buffer問題

解決自:https://stackoverflow.com/questions/66156756/how-to-polylfill-buffer-for-jsonwebtoken-in-wepack-5

成果

測(cè)試用 xlsx

寫在后面

上文中的測(cè)試代碼只有加載本地 xlsx 文件,如果需要從服務(wù)器下載再替換,無論您使用什么網(wǎng)絡(luò)加載框架都需要注意:
xlsx-template 框架需要傳入 buffer 類型數(shù)據(jù),所以請(qǐng)做轉(zhuǎn)換,或直接找以 buffer 類型下載的網(wǎng)絡(luò)框架

xlsx-template 的 generate 函數(shù)注意傳入 { type: 'blob' } 這樣直接可以保存成 blob 類型數(shù)據(jù),方便后面向服務(wù)器進(jìn)行網(wǎng)絡(luò)上傳

為了避免后續(xù)文中出現(xiàn)的庫有更新,使本文內(nèi)容出現(xiàn)偏差,提供本測(cè)試項(xiàng)目的 package.json 中各個(gè)庫的版本號(hào):

    "assert": "^2.0.0",
    "constants-browserify": "^1.0.0",
    "core-js": "^3.8.3",
    "docxtemplater": "^3.37.11",
    "file-saver": "^2.0.5",
    "jszip-utils": "^0.1.0",
    "path": "^0.12.7",
    "pizzip": "^3.1.4",
    "stream-browserify": "^3.0.0",
    "util": "^0.12.5",
    "vue": "^3.2.13",
    "vue-router": "^4.0.3",
    "webpack": "^5.88.1",
    "xlsx-template": "^1.4.3"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容