NodeJs之word文件生成与解析
一,介绍与需求
1.1,介绍
1,officegen 模块可以为Microsoft Office 2007及更高版本生成Office Open XML文件。此模块不依赖于任何框架,您不需要安装Microsoft Office,因此您可以将它用于任何类型的 JavaScript 应用程序。输出也是流而不是文件,不依赖于任何输出工具。此模块应适用于支持Node.js 0.10或更高版本的任何环境,包括Linux,OSX和Windows。
2,textract文本提取节点模块。
3,pdf2json是一个节点。js模块解析和转换PDF从二进制到json格式,它是用PDF构建的。并通过浏览器外的交互式表单元素和文本内容解析对其进行扩展。其目标是在web服务中包装时启用带有交互式表单元素的服务器端PDF解析,并在作为命令行实用程序使用时启用将本地PDF解析为json文件。
1.2,需求
二,文件生成导出
第一步:安装officegen
1 cnpm install officegen --save
第二步:引入officegen
1 var officegen = require('officegen');
2 var fs = require('fs');
3 var docx = officegen('docx');//word
4 var pptx = officegen('pptx');//pptx
第三步:使用officegen docx
1 ...
2
3 docx.on('finalize', function (written) {
4 console.log('Finish to create Word file.\nTotal bytes created: ' + written + '\n');
5 });
6
7
8 docx.on('error', function (err) {
9 console.log(err);
10 });
11
12 ...
13
14 //var tows = ['id', 'provinceZh', 'leaderZh', 'cityZh', 'cityEn'];//创建一个和表头对应且名称与数据库字段对应数据,便于循环取出数据
15 var pObj = docx.createP({ align: 'center' });// 创建行 设置居中 大标题
16 pObj.addText('全国所有城市', { bold: true, font_face: 'Arial', font_size: 18 });// 添加文字 设置字体样式 加粗 大小
17
18 // let towsLen = tows.length
19 let dataLen = data.length
20 for (var i = 0; i < dataLen; i++) {//循环数据库得到的数据,因为取出的数据格式为
21 //[{"id" : "101010100","provinceZh" : "北京","leaderZh" : "北京","cityZh" : "北京","cityEn" : "beijing"},{…………},{…………}]
22 /************************* 文本 *******************************/
23 // var pObj = docx.createP();//创建一行
24 // pObj.addText(`(${i+1}), `,{ bold: true, font_face: 'Arial',});
25 // pObj.addText(`省级:`,{ bold: true, font_face: 'Arial',});
26 // pObj.addText(`${data[i]['provinceZh']} `,);
27 // pObj.addText(`市级:`,{ bold: true, font_face: 'Arial',});
28 // pObj.addText(`${data[i]['leaderZh']} `);
29 // pObj.addText(`县区:`,{ bold: true, font_face: 'Arial',});
30 // pObj.addText(`${data[i]['cityZh']}`);
31
32 /************************* 表格 *******************************/
33 let SingleRow = [data[i]['id'], data[i]['provinceZh'], data[i]['leaderZh'], data[i]['cityZh']]
34 table.push(SingleRow)
35 }
36 docx.createTable(table, tableStyle);
37 var out = fs.createWriteStream('out.docx');// 文件写入
38 out.on('error', function (err) {
39 console.log(err);
40 });
41 var result = docx.generate(out);// 服务端生成word
42 res.writeHead(200, {
43 // 注意这里的type设置,导出不同文件type值不同application/vnd.openxmlformats-officedocument.wordprocessingml.document
44 "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
45 'Content-disposition': 'attachment; filename=out' + moment(new Date().getTime()).format('YYYYMMDDhhmmss') + '.docx'
46 });
47 docx.generate(res);// 客户端导出word
第四步:抛出接口
1 router.put('/download/word', function (req, res) {
2 console.log('exportWord-------------');
3 docx.on('finalize', function (written) {
4 console.log('Finish to create Word file.\nTotal bytes created: ' + written + '\n');
5 });
6
7
8 docx.on('error', function (err) {
9 console.log(err);
10 });
11 let fields = {
12 id: '',
13 provinceZh: '',
14 leaderZh: '',
15 cityZh: '',
16 cityEn: ''
17 }
18 var table = [
19 [{
20 val: "No.",
21 opts: {
22 align: "center",
23 vAlign: "center",
24 sz: '36',
25 // cellColWidth: 42,
26 // b:true,
27 // sz: '48',
28 // shd: {
29 // fill: "7F7F7F",
30 // themeFill: "text1",
31 // "themeFillTint": "80"
32 // },
33 // fontFamily: "Avenir Book"
34 }
35 }, {
36 val: "省份",
37 opts: {
38 align: "center",
39 vAlign: "center",
40 sz: '36',
41 // b:true,
42 // color: "A00000",
43 // align: "right",
44 // shd: {
45 // fill: "92CDDC",
46 // themeFill: "text1",
47 // "themeFillTint": "80"
48 // }
49 }
50 }, {
51 val: "市",
52 opts: {
53 align: "center",
54 vAlign: "center",
55 sz: '36',
56 // cellColWidth: 42,
57 // b:true,
58 // sz: '48',
59 // shd: {
60 // fill: "92CDDC",
61 // themeFill: "text1",
62 // "themeFillTint": "80"
63 // }
64 }
65 }, {
66 val: "区/县",
67 opts: {
68 align: "center",
69 vAlign: "center",
70 sz: '36',
71 // cellColWidth: 42,
72 // b:true,
73 // sz: '48',
74 // shd: {
75 // fill: "92CDDC",
76 // themeFill: "text1",
77 // "themeFillTint": "80"
78 // }
79 }
80 }],
81 ]
82
83 var tableStyle = {
84 tableColWidth: 2400,
85 tableSize: 24,
86 tableColor: "ada",
87 tableAlign: "center",
88 tableVAlign: "center",
89 tableFontFamily: "Comic Sans MS",
90 borders: true
91 }
92
93 MongoDbAction.getFieldsByConditions('AllCity', {}, fields, function (err, data) {//根据需求查询想要的字段
94 if (err) {
95 //执行出错
96 } else {
97 //var tows = ['id', 'provinceZh', 'leaderZh', 'cityZh', 'cityEn'];//创建一个和表头对应且名称与数据库字段对应数据,便于循环取出数据
98 var pObj = docx.createP({ align: 'center' });// 创建行 设置居中 大标题
99 pObj.addText('全国所有城市', { bold: true, font_face: 'Arial', font_size: 18 });// 添加文字 设置字体样式 加粗 大小
100
101 // let towsLen = tows.length
102 let dataLen = data.length
103 for (var i = 0; i < dataLen; i++) {//循环数据库得到的数据,因为取出的数据格式为
104 //[{"id" : "101010100","provinceZh" : "北京","leaderZh" : "北京","cityZh" : "北京","cityEn" : "beijing"},{…………},{…………}]
105 /************************* 文本 *******************************/
106 // var pObj = docx.createP();//创建一行
107 // pObj.addText(`(${i+1}), `,{ bold: true, font_face: 'Arial',});
108 // pObj.addText(`省级:`,{ bold: true, font_face: 'Arial',});
109 // pObj.addText(`${data[i]['provinceZh']} `,);
110 // pObj.addText(`市级:`,{ bold: true, font_face: 'Arial',});
111 // pObj.addText(`${data[i]['leaderZh']} `);
112 // pObj.addText(`县区:`,{ bold: true, font_face: 'Arial',});
113 // pObj.addText(`${data[i]['cityZh']}`);
114
115 /************************* 表格 *******************************/
116 let SingleRow = [data[i]['id'], data[i]['provinceZh'], data[i]['leaderZh'], data[i]['cityZh']]
117 table.push(SingleRow)
118 }
119 docx.createTable(table, tableStyle);
120 var out = fs.createWriteStream('out.docx');// 文件写入
121 out.on('error', function (err) {
122 console.log(err);
123 });
124 var result = docx.generate(out);// 服务端生成word
125 res.writeHead(200, {
126 // 注意这里的type设置,导出不同文件type值不同application/vnd.openxmlformats-officedocument.wordprocessingml.document
127 "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
128 'Content-disposition': 'attachment; filename=out' + moment(new Date().getTime()).format('YYYYMMDDhhmmss') + '.docx'
129 });
130 docx.generate(res);// 客户端导出word
131 }
132 });
133
134 });
第五步:前端调用
下载调用方法
1 downloadWordOper() {
2 // var url = "http://localhost:8880/api/v1/yingqi/download/word";
3 // window.location = url;//这里不能使用get方法跳转,否则下载不成功
4 this.$http(downloadWord()).then((res)=>{
5 //这里res.data是返回的blob对象
6 var blob = new Blob([res.data], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8'}); //application/vnd.openxmlformats-officedocument.wordprocessingml.document这里表示doc类型
7 downloadFile(blob,'word','docx')
8 })
9
10 },
downloadFile方法代码如下:
1 /**
2 *下载文件
3 * @param blob :返回数据的blob对象
4 * @param tagFileName :下载后文件名标记
5 * @param fileType :文件类 word(docx) excel(xlsx) ppt等
6 */
7 export function downloadFile(blob,tagFileName,fileType) {
8 var downloadElement = document.createElement('a');
9 var href = window.URL.createObjectURL(blob); //创建下载的链接
10 downloadElement.href = href;
11 downloadElement.download = tagFileName+moment(new Date().getTime()).format('YYYYMMDDhhmmss')+'.'+fileType; //下载后文件名
12 document.body.appendChild(downloadElement);
13 downloadElement.click(); //点击下载
14 document.body.removeChild(downloadElement); //下载完成移除元素
15 window.URL.revokeObjectURL(href); //释放掉blob对象
16 }
第六步:下载后的效果
ppt生成下载类似,只是设置的writeHead类型与使用的方法不一样
1 router.put('/download/createPpt', function (req, res) {
2 console.log('exportPpt-------------');
3 pptx.on('finalize', function (written) {
4 console.log('Finish to create ppt file.\nTotal bytes created: ' + written + '\n');
5 });
6
7
8 pptx.on('error', function (err) {
9 console.log(err);
10 });
11
12 let slide1 = pptx.makeNewSlide();//创建一个新幻灯片
13 slide1.title = 'PPT文件';
14 slide1.addText('Office generator', {
15 y: 66, x: 'c', cx: '50%', cy: 60, font_size: 48,
16 color: '0000ff'
17 });
18
19 slide1.addText('Big Red', {
20 y: 250, x: 10, cx: '70%',
21 font_face: 'Wide Latin', font_size: 54,
22 color: 'cc0000', bold: true, underline: true
23 });
24
25 var out = fs.createWriteStream('out.pptx');// 文件写入
26 out.on('error', function (err) {
27 console.log('error2===',err);
28 });
29 var result = pptx.generate(out);// 服务端生成ppt
30 res.writeHead(200, {
31 // 注意这里的type设置,导出不同文件type值不同application/vnd.openxmlformats-officedocument.presentationml.presentation
32 // "Content-Type": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
33 // 'Content-disposition': 'attachment; filename=out' + moment(new Date().getTime()).format('YYYYMMDDhhmmss') + '.pptx'
34 "Content-Type": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
35 'Content-disposition': 'attachment; filename=surprise.pptx'
36 });
37 pptx.generate(res);// 客户端导出ppt
38
39 });
三,文件上传解析
3.1,word文档解析
第一步:安装textract
1 cnpm install textract --save
第二步:引入textract
1 //引入textract解析word模块
2 var textract = require('textract');//对于docx文件,您可以使用textract,它将从.docx文件中提取文本。
3 var fs = require('fs');
第三步:解析文档
1 function parseWord(excelConfig, res) {
2 textract.fromFileWithPath(excelConfig.excel_Dir, function (error, text) {
3 if (error) {
4 res.status(200).json({
5 httpCode: 200,
6 message: '导入解析失败',
7 data: error,
8 returnValue: 0
9 });
10 } else {
11 res.status(200).json({
12 httpCode: 200,
13 message: '导入成功',
14 data: {
15 result: text
16 },
17 returnValue: 1
18 });
19 }
20 })
21 }
第四步:解析后删除文档
1 fs.unlink(excelConfig.excel_Dir, function (err) {
2 if (err) throw err;
3 console.log("删除文件" + excelConfig.excel_Dir + "成功")
4 })
第五步:抛出接口调用后的效果
3.2,pdf文档解析
第一步:安装pdf2json
1 cnpm install pdf2json --save
第二步:引入pdf2json
1 var PDFParser = require("pdf2json");
2 var fs = require('fs');
第三步:解析文档
1 function parsePdf(excelConfig, res) {
2 var pdfParser = new PDFParser(this, 1);
3 pdfParser.loadPDF(excelConfig.excel_Dir);
4 pdfParser.on("pdfParser_dataError", errData => {
5 res.status(200).json({
6 httpCode: 200,
7 message: '导入解析失败',
8 data: errData,
9 returnValue: 0
10 });
11 });
12 pdfParser.on("pdfParser_dataReady", pdfData => {
13 let data = pdfParser.getRawTextContent()
14 fs.writeFile('./uploads/test.txt', data, function (err) {
15 if (err) {
16 throw err;
17 }
18 });
19 res.status(200).json({
20 httpCode: 200,
21 message: '导入成功',
22 data: {
23 result: data
24 },
25 returnValue: 1
26 });
27 });
28 }
第四步:解析后删除文档
1 fs.unlink(excelConfig.excel_Dir, function (err) {
2 if (err) throw err;
3 console.log("删除文件" + excelConfig.excel_Dir + "成功")
4 })
第五步:抛出接口调用后的效果