????在線編輯office文檔(word恳啥、excel、powerpoint等)的實(shí)現(xiàn)方式可以歸集為兩種:
????1扣蜻、純前端的在線編輯,如點(diǎn)聚WebOffice及塘、金格WebOffice莽使、PageOffice、ntko office笙僚、DSOFramer等芳肌,一般基于ActiveX控件實(shí)現(xiàn),在各個(gè)瀏覽器逐步嚴(yán)控甚至禁止各類客戶端控件的大背景下肋层,這些解決方案的應(yīng)用空間將會(huì)越來(lái)越小亿笤。當(dāng)然近年也出現(xiàn)了一些基于云端office的解決方案,例如暢寫(xiě)office槽驶,前端不再依賴ActiveX控件责嚷,但云端服務(wù)器上的留痕始終讓人不放心鸳兽。
????2掂铐、后端創(chuàng)建、前端預(yù)覽方式揍异,如果要修改后臺(tái)創(chuàng)建的office文檔全陨,則可以采用前端下載后修改,然后在上傳更新后臺(tái)文檔衷掷;當(dāng)然也可以有限集成純前端在線編輯功能辱姨,以對(duì)后臺(tái)創(chuàng)建的文檔進(jìn)行編輯,雖然筆者不建議這么做戚嗅,畢竟前端的在線編輯功能再?gòu)?qiáng)大雨涛,也沒(méi)有在自己電腦上用office進(jìn)行編輯來(lái)的方便、靈活懦胞。
????本文主要介紹第二種方式替久,即“后端創(chuàng)建、前端預(yù)覽”的相關(guān)實(shí)現(xiàn)方式躏尉,和注意事項(xiàng)蚯根。包括如下內(nèi)容:
1、 開(kāi)發(fā)環(huán)境
2胀糜、 后端創(chuàng)建方式一:新創(chuàng)建文檔
3颅拦、 后端創(chuàng)建方式二:基于模板創(chuàng)建文檔
4蒂誉、 前端預(yù)覽
5、 幾個(gè)坑
一距帅、 開(kāi)發(fā)環(huán)境
????前端右锨,vuejs,UI是quasar
????后端碌秸,nodejs
二陡蝇、 后端創(chuàng)建方式一:新創(chuàng)建文檔
????基于officegen(https://github.com/Ziv-Barber/officegen)實(shí)現(xiàn)office(word、excel哮肚、powerpoint)文檔的創(chuàng)建登夫。
? ?安裝組件: npm i officegen --save-dev
? ??實(shí)現(xiàn)代碼:
import fs from 'fs'
import path from 'path'
import officegen from 'officegen'
module.exports = {
????createpgbg:async (rwbh) => {
????//創(chuàng)建word對(duì)象
????let docx = officegen('docx') ;
????docx.on('finalize', function(written){
????????console.log( '成功創(chuàng)建了word文件.' ) }) // Officegen calling this function to report errors:
????docx.on('error', function(err) { console.log(err) })
????let pObj = docx.createP() ;
????pObj.addText('Simple')
????pObj.addText(' with color', { color: '000088' })
????pObj.addText(' and back color.', { color: '00ffff', back: '000088' })
????pObj = docx.createP() pObj.addText('Since ')
????pObj.addText('officegen 0.2.12', { back: '00ffff', shdType: 'pct12', shdColor: 'ff0000' }) // Use pattern in the background.
????pObj.addText(' you can do ')
????pObj.addText('more cool ', { highlight: true }) // Highlight!
????pObj.addText('stuff!', { highlight: 'darkGreen' }) // Different highlight color.
????pObj = docx.createP()
????pObj.addText('Even add ')
????pObj.addText('external link', { link: 'https://github.com' })
????pObj.addText('!') pObj = docx.createP()
????pObj.addText('Bold + underline', { bold: true, underline: true })
????pObj = docx.createP({ align: 'center' })
????pObj.addText('Center this text', { border: 'dotted', borderSize: 12, borderColor: '88CCFF' })
????pObj = docx.createP()
????pObj.options.align = 'right'
????pObj.addText('Align this text to the right.')
????pObj = docx.createP()
????pObj.addText('Those two lines are in the same paragraph,')
????pObj.addLineBreak()
????pObj.addText('but they are separated by a line break.')
????docx.putPageBreak()
????pObj = docx.createP()
????pObj.addText('Fonts face only.', { font_face: 'Arial' })
????pObj.addText(' Fonts face and size.', { font_face: 'Arial', font_size: 40 })
????docx.putPageBreak()
????pObj = docx.createP()
????pObj.addImage('assets/uploads/1.jpg')
????let out = fs.createWriteStream('example1.docx')
????out.on('error', function(err) { console.log(err) })
????docx.generate(out)
}
}
三、后端創(chuàng)建方式二:基于模板創(chuàng)建文檔
????基于docxtemplater組件(https://github.com/open-xml-templating/docxtemplater)實(shí)現(xiàn)基于模板的office(word允趟、excel恼策、powerpoint)文檔創(chuàng)建。
????安裝組件:npm i docxtemplater?--save-dev
? ? ? ? ? ? ? ? ? ? ? npm i jszip@2.0.0 --save-dev
? ? ? ? ? ? ? ? ? ? ? ?npm i docxtemplater-image-module-free--save-dev
????實(shí)現(xiàn)代碼:
import fs from 'fs'
import path from 'path'
import jszip from 'jszip'
import docxtemplater from 'docxtemplater'
import docximagetemplater from'docxtemplater-image-module-free'
module.exports = {
? createpgbg:async(rwbh) => {
??? //打開(kāi)word模板文件
??? let content =fs.readFileSync(path.resolve(__dirname,'../../assets/report/pgbgV2019.docx'),'binary');
??? let zip = newjszip(content) ;
??? let doc = newdocxtemplater() ;
??? let opts = {
????? centered:false,
?????fileType:'docx',
????? getImage:function(tagValue, tagName) {
??????? returnfs.readFileSync(path.join(__dirname, '../../assets/uploads/' + tagValue));
????? },
????? getSize:function(img, tagValue, tagName) {
??????? if(tagName== "a57"){
????????? return[350, 370];
??????? }
??????? elseif(tagName == "a58"){
????????? return[240, 180];
??????? }
??????? elseif(tagName == "a59"){
????????? return[240, 160];
??????? }
??????? else{
????????? return[100, 100];
??????? };
????? }
??? };
???doc.attachModule(new docximagetemplater(opts)) ;
???doc.loadZip(zip) ;
??? //裝載數(shù)據(jù)
??? doc.setData({
????? a53:'八一路',
????? a54:'蘇州東路',
????? a55:'康平路',
????? a56:'小區(qū)內(nèi)水潮剪、電涣楷、氣、有線電視等基礎(chǔ)設(shè)施配套齊全抗碰,附近有學(xué)校狮斗、超市、菜場(chǎng)弧蝇,商業(yè)碳褒、服務(wù)網(wǎng)點(diǎn)齊全,附近有公交站臺(tái)看疗,生活較方便',
?????a57:'img1.jpg',
?????a58:'img2.jpg',
?????a59:'img3.jpg'
??? }) ;
??? try{
????? //替換數(shù)據(jù)
????? doc.render();
???}catch(error){};
??? //保存文件
??? let buf =doc.getZip().generate({type:'nodebuffer'}) ;
???fs.writeFileSync(path.resolve(__dirname,'../../assets/report/pgbg.docx'),buf);
??? let filename ='2020-pgbg.docx' ;
??? return{fileurl:filename} ;
? }
}
四沙峻、前端預(yù)覽
前端預(yù)覽的選擇挺多,其中有三種方式經(jīng)過(guò)筆者實(shí)際使用两芳,感覺(jué)挺不錯(cuò):
方式1:<iframe
src='https://view.officeapps.live.com/op/view.aspx?src=你需要展示的word文檔' />
方式2:<iframe src='http://ow365.cn/?i=1&furl=你需要展示的word文檔' />
方式3:<iframe src='http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=1&_xdoc=你需要展示的word文檔' />
?????以上三種方式都要求“你需要展示的word文檔”必須是互聯(lián)網(wǎng)上能夠訪問(wèn)的地址和文件名摔寨,此外一些使用心得如下:
????1、方式1免費(fèi)怖辆,的文檔地址必須用encodeURIComponent進(jìn)行編碼是复、地址必須為域名(不能用ip地址)、端口貌似也只能為80竖螃,文件大小有限制(word淑廊、ppt文件小于10M,excel文件小于5M)斑鼻。
????2蒋纬、方式2有限免費(fèi),使用前必須前在網(wǎng)站上注冊(cè)(免費(fèi)版單文件<5M、日訪問(wèn)量<500次)蜀备。但“你需要展示的word文檔”支持IP地址訪問(wèn)关摇,而且地址不需要編碼。缺點(diǎn)就是每頁(yè)都有一個(gè)OW365的LOGO碾阁,但不影響效果输虱。
????3、方式3免費(fèi)脂凶,而且支持IP地址訪問(wèn)宪睹、地址也不需要編碼、不需要注冊(cè)賬號(hào)蚕钦。缺點(diǎn)就是亭病,顯示的時(shí)候?qū)嶋H上是自動(dòng)轉(zhuǎn)換成了HTML,所以沒(méi)有office里的那種顯示質(zhì)感嘶居。另外還有一個(gè)小缺點(diǎn)就是顯示的速度有些慢罪帖,不過(guò)只要耐心,還是可以接受的邮屁。
五整袁、幾個(gè)坑
1、word模板中的圖形顯示模塊
????Docxtemplater其實(shí)包含了images模塊(即支持在word模板中插入圖片的功能)佑吝,但這個(gè)模塊要收費(fèi)坐昙,所以只能另找一個(gè)免費(fèi)的images模塊和Docxtemplater配合使用,而網(wǎng)上大部分文檔都推薦使用open-docxtemplater-image-module芋忿,而且還提供了詳細(xì)的實(shí)現(xiàn)代碼炸客,但經(jīng)過(guò)筆者實(shí)際測(cè)試,不但顯示不了圖片盗飒,甚至還影響到Docxtemplater對(duì)文字模板的替換嚷量。
????而用docxtemplater-image-module-free組件,就可以正常配合Docxtemplater顯示出圖片逆趣,以上代碼就是經(jīng)過(guò)運(yùn)行驗(yàn)證的。
2嗜历、壓縮解壓組件
????在word模板創(chuàng)建中需要用到壓縮和解壓組件宣渗,Docxtemplater只支持2.0版本的jszip,如果安裝的是3.0+版本的jszip則在運(yùn)行時(shí)就會(huì)報(bào)錯(cuò)梨州,而且不能正確創(chuàng)建出word文檔痕囱。這就是以上示例中強(qiáng)制安裝2.0版jszip的原因。
????但如果使用pizzip暴匠,就沒(méi)有版本的限制鞍恢,可以正常使用。