NodeJS调用WPS进行文档转换、文件服务器及WS服务器、PDF转图片

前言

在使用Electron客户端的时候,文档转换是个问题,没有原生的转换库,这里只能只能通过WPS进行转换。

利用WPS进行文档转换

注意

安装的时候需要电脑上的Python版本为2.7,否则编译报错。

设置环境

1
2
npm config set python python2.7
npm config set msvs_version 2017

安装

1
npm install winax --msvs_version=2017

使用

1
2
var winax = require('winax');
var con = new winax.Object('ADODB.Connection');

文档格式转换

文档格式转换 支持 wps、wpt、doc、docx、dot、txt等所有文档格式文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var winax = require('winax');
var Variant = winax.Variant;

var source_path = "D:\\Tools\\1.doc";
var target_path = "D:\\Tools\\1.pdf";

var wax = new winax.Object("KWPS.Application", {
activate: true
});

try {
var doc = wax.Documents.Open(new Variant(source_path), new Variant(true), new Variant(true));
doc.SaveAs(new Variant(target_path), new Variant(17));
doc.Close();
} catch (e) {
console.info(e);
} finally {
wax.Quit();
}

幻灯片格式转换

幻灯片格式转换 支持ppt、pps、pptx、ppsx、dps、dpt、pot、uof

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var winax = require('winax');
var Variant = winax.Variant;

var source_path = "D:\\Tools\\1.pptx";
var target_path = "D:\\Tools\\2.pdf";

var wax = new winax.Object("KWPP.Application", {
activate: true
});

try {
var doc = wax.Presentations.Open(new Variant(source_path), new Variant(true));
doc.SaveAs(new Variant(target_path), new Variant(32));
doc.Close();
} catch (e) {
console.info(e);
} finally {
wax.Quit();
}

表格格式转换

表格格式转换 支持et、ett、xls、xlsx、xlt、uof、prn、csv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var winax = require('winax');
var Variant = winax.Variant;

var source_path = "D:\\Tools\\1.xlsx";
var target_path = "D:\\Tools\\3.pdf";

var wax = new winax.Object("KET.Application", {
activate: true
});

try {
var doc = wax.Workbooks.Open(new Variant(source_path), new Variant(0), new Variant(true));
doc.ExportAsFixedFormat(new Variant(0), new Variant(target_path), new Variant(0));
doc.Close();
} catch (e) {
console.info(e);
} finally {
wax.Quit();
}

PDF转图片

方式1(不推荐)

注意

这种方式 会出现转换的文字乱码。

安装

1
npm i pdf-img-convert

示例

1
2
3
4
5
6
7
8
9
10
11
12
let pdf2img = require('pdf-img-convert');
const fs = require('fs');
let outputImages2 = pdf2img.convert('D:\\Tools\\Docs\\01.pdf');
let savePath = 'D:\\Tools\\Docs\\images\\';
outputImages2.then(function (outputImages) {
for (let i = 0; i < outputImages.length; i++)
fs.writeFile(savePath + i + ".png", outputImages[i], function (error) {
if (error) {
console.error("Error: " + error);
}
});
});

如果node-canvas无法安装

原因是GTK无法下载

win64下载地址(推荐):http://ftp.gnome.org/pub/gnome/binaries/win64/gtk+/2.22/gtk+-bundle_2.22.1-20101229_win64.zip

下载GTK包并解压在C:\GTK目录下

重新安装即可

1
npm i node-canvas

方式2 Ghostscript(推荐)

这种方式效果较好,就是引用的exe和dll会增加将近11M。

gs.exe的同级目录下运行下面的命令

获取页数

1
./gs -q -dNODISPLAY -c "(D:/Project/Node/Pdf2PngforWindows/doc/1.pdf) (r) file runpdfbegin pdfpagecount = quit"

转换某页

1
./gs -dQUIET -dPARANOIDSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=png16m -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r100 -dFirstPage=1 -dLastPage=1 -sOutputFile=C:\Users\ADMINI~1\AppData\Local\Temp\tmp-8468uujQmrsdRJ21.png "D:\Project\Node\Pdf2PngforWindows/doc/1.pdf"

我们就可以根据页数进行逐页转换。

相关参数如下说明:

  • -dQUIET, 安静的意思,指代执行过程中尽可能少的输出日志等信息。(也可以简写为-q
  • -dNOSAFER, 通过命令行运行
  • -dBATCH, 执行到最后一页后退出
  • -dNOPAUSE, 每一页转换之间没有停顿
  • -dNOPROMPT, 没有相关提示
  • -dFirstPage=1, 从第几页开始
  • -dLastPage=5, 到第几页结束
  • -sDEVICE=png16m, 转换输出的文件类型装置,默认值为x11alpha
  • -g720x1280, 图片像素(-g<width>x<height>),一般不指定,使用默认输出
  • -r300, 图片分辨率(即图片解析度为300dpi),默认值好像是72
  • -sOutputFile=/opt/shanhy/error1png/%d.png, 图片输出路径,使用%d%ld输出页数

工具类

pdf2png.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
let exec = require('child_process').exec;
const path = require("path");
let initialized = false;

exports.ghostscriptPath = __dirname + "\\executables\\ghostScript";
// for linux compability
exports.ghostscriptPath = exports.ghostscriptPath.split("\\").join("/");

// 获取页数
function getPageCount(pdfPath) {
return new Promise((resolve, reject) => {
pdfPath = pdfPath.replace(/\\/g, "/");
let cmd = 'gs -q -dNODISPLAY -c "(' + pdfPath + ') (r) file runpdfbegin pdfpagecount = quit"';
exec(cmd, function (error, stdout, stderr) {
if (error !== null) {
reject(error);
return;
}
// Remove line break (\n) at the end
let pageCount = stdout.substr(0, stdout.length - 1);
resolve(pageCount);
});
});
}

//导出页面
function exportImage(pdfPath, imageFilepath, quality, i) {
return new Promise((resolve, reject) => {
let cmd = "gs -dQUIET -dPARANOIDSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=png16m -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r" +
quality +
" -dFirstPage=" + i +
" -dLastPage=" + i +
" -sOutputFile=" + imageFilepath +
" " +
'"' + pdfPath + '"';
exec(cmd, function (error, stdout, stderr) {
if (error !== null) {
reject(error);
} else {
resolve(imageFilepath);
}
});
})
}

exports.convert = async function (pdfPath, savePath, quality) {
if (!initialized) {
process.env.Path += ";" + exports.ghostscriptPath;
initialized = true;
}

quality = quality || 100;
let imageAll = [];
try {
let pagetotal = await getPageCount(pdfPath);
for (let i = 1; i <= pagetotal; i++) {
let imagePath = path.join(savePath, "img_" + i + ".png")
await exportImage(
pdfPath,
imagePath,
quality,
i
)
imageAll.push(imagePath);
}
return imageAll;
} catch (e) {
return [];
}
};

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const pdf2png = require("./lib/pdf2png.js");
const fs = require("fs");

let gsPath = __dirname + "\\executables\\ghostScript";
pdf2png.ghostscriptPath = gsPath;

let pdfPath = __dirname + "/doc/1.pdf";
let savePath = __dirname + "/doc/imgs/"
if (!fs.existsSync(savePath)) {
fs.mkdirSync(savePath);
}

async function main() {
let pathAll = await pdf2png.convert(pdfPath, savePath);
console.log(pathAll);
}
main();

示例代码

https://gitee.com/psvmc/pdf2png_win

文件服务器

安装依赖

1
2
npm install connect
npm install serve-static

代码

1
2
3
4
5
6
7
var connect = require("connect");
var serveStatic = require("serve-static");

var app = connect();
app.use(serveStatic("D:\\Tools"));
app.listen(5000);
console.info("文件服务器启动了!");

WS服务器

1
2
3
4
5
6
7
8
9
10
11
const WebSocketServer = require('ws').Server;
wss = new WebSocketServer({port: 12122});
wss.on('connection', (ws) => {
// 有客户端连接时, 打印一条日志
console.log('client connected');
// 并且创建'message'监听
ws.on('message', (message) => {
// 直接将消息打印出来
console.log(message);
});
});