概述
本篇博客以简单的示例代码分别在Windows和Linux环境下完成Word转PDF的文档转换。
文章提供SpringBoot + Vue3的示例代码。
文章为什么要分为Windows和Linux环境?
因为在如下提供的Windows后端示例代码中使用documents4j库做转换,此库需要调用命令行工具,并且需要安装Microsoft Word,但在Linux上无法安装Microsoft Word,因此如下提供了两份后端代码。
过程
前端传入word文件 -> 后端处理 -> 返回转换后的字节数组(byte[])
Windows后端代码
maven依赖
<dependency><groupId>com.documents4j</groupId><artifactId>documents4j-local</artifactId><version>1.0.3</version>
</dependency><dependency><groupId>com.documents4j</groupId><artifactId>documents4j-transformer-msoffice-word</artifactId><version>1.0.3</version>
</dependency>
示例代码
// controller接口
@PostMapping("/upload")public byte[] convertDocxToPdf(@RequestParam("file") MultipartFile file) throws IOException {if (!file.getOriginalFilename().endsWith(".docx")) {throw new IllegalArgumentException("文件类型不支持");}try (InputStream docxInputStream = file.getInputStream();ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {IConverter converter = LocalConverter.builder().build();converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();return outputStream.toByteArray();}}
CentOS后端代码
maven依赖
<dependency><groupId>org.jodconverter</groupId><artifactId>jodconverter-local</artifactId><version>4.4.2</version>
</dependency>
示例代码
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)public byte[] uploadFile(@RequestParam("file") MultipartFile file) throws IOException, OfficeException {if (file.getOriginalFilename().endsWith(".docx")) {LocalOfficeManager officeManager = LocalOfficeManager.install();try {officeManager.start();DocumentConverter converter = LocalConverter.builder().officeManager(officeManager).build();ByteArrayOutputStream out = new ByteArrayOutputStream();converter.convert(file.getInputStream()).as(DefaultDocumentFormatRegistry.DOCX).to(out).as(DefaultDocumentFormatRegistry.PDF).execute();return out.toByteArray();} finally {OfficeUtils.stopQuietly(officeManager);}} else {throw new IOException("文件类型不支持");}}
*** 当使用上方的代码进行word转pdf之后,输出的很大可能会出现中文文字不能正确显示,文字全部变成小矩形框。
这是因为在linux上没有中文字体库导致的。
在centos7中安装中文字体库
1.首先检查安装所需要的工具
yum -y install fontconfig
yum -y install ttmkfdir
2.之后检查/usr/share目录是否有fonts 和 fontconfig
3.创建chinese目录,用于存放我们需要的字体
在/usr/share/fonts下创建chinese
4.下载需要的字体
我们到自己的windows电脑上查找想要的字体,访问C:\Windows\Fonts
可以搜索自己文档转换过程中需要的字体,例如:宋体
将字体拷贝放到centos的/usr/share/fonts/chinese目录中,并修改chinese目录的权限:
chmod -R 755 /usr/share/fonts/chinese
5.执行命令,生成 TrueType 字体的字体度量
ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
6.配置刚才创建中文字体目录,使之生效即可。
vi /etc/fonts/fonts.conf
7.执行命令,刷新字体缓存
fc-cache
至此,重新访问后端服务进行word转pdf会发现字体成功显示。
前端测试代码
在此提供与后端代码配套测试的前端代码(vue3)
<template><div><div id="my_ipt"><label for="ipt" class="upload-button">上传文件(Word 或 PDF)</label><input id="ipt" type="file" @change="uploadFile" accept=".pdf,.docx">
</div><hr><iframe v-if="fileSrc" :src="fileSrc" width="100%" height="600px"></iframe></div>
</template><script setup>
import { ref } from 'vue';
import axios from 'axios'; const fileSrc = ref(null);const uploadFile = async (event) => {const file = event.target.files[0];if (file) {if (file.type === 'application/pdf') {fileSrc.value = URL.createObjectURL(file);} else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {const formData = new FormData();formData.append('file', file);const response = await axios.post('/doc/upload', formData, {responseType: 'blob',headers: {'Content-Type': 'multipart/form-data'}});fileSrc.value = URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' }));} }
};
</script><style scoped>
.upload-button {background-color: #4CAF50;border: none;color: white;padding: 10px 20px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;cursor: pointer;border-radius: 5px;
}.upload-button:hover {background-color: #3e8e41;
}</style>