基于Nodejs的word(office)文檔實(shí)現(xiàn)方法(一)

????在線編輯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)

}

}

以上代碼生成的word效果


三、后端創(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} ;

? }

}


WORD模板


創(chuàng)建的word文檔效果

四沙峻、前端預(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文檔' />


方式3的實(shí)現(xiàn)效果

?????以上三種方式都要求“你需要展示的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)有版本的限制鞍恢,可以正常使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市帮掉,隨后出現(xiàn)的幾起案子弦悉,更是在濱河造成了極大的恐慌,老刑警劉巖蟆炊,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稽莉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡涩搓,警方通過(guò)查閱死者的電腦和手機(jī)污秆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)昧甘,“玉大人良拼,你說(shuō)我怎么就攤上這事〕浔撸” “怎么了将饺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)痛黎。 經(jīng)常有香客問(wèn)我予弧,道長(zhǎng),這世上最難降的妖魔是什么湖饱? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任掖蛤,我火速辦了婚禮,結(jié)果婚禮上井厌,老公的妹妹穿的比我還像新娘蚓庭。我一直安慰自己,他們只是感情好仅仆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布器赞。 她就那樣靜靜地躺著,像睡著了一般墓拜。 火紅的嫁衣襯著肌膚如雪港柜。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天咳榜,我揣著相機(jī)與錄音夏醉,去河邊找鬼。 笑死涌韩,一個(gè)胖子當(dāng)著我的面吹牛畔柔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播臣樱,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼靶擦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼腮考!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起玄捕,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤踩蔚,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后桩盲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體寂纪,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年赌结,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捞蛋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柬姚,死狀恐怖拟杉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情量承,我是刑警寧澤搬设,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站撕捍,受9級(jí)特大地震影響拿穴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜忧风,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一默色、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狮腿,春花似錦腿宰、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至贴硫,卻和暖如春椿每,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夜畴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工拖刃, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贪绘。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像央碟,于是被迫代替她去往敵國(guó)和親税灌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子均函,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355