最近项目需要做在线预览文档功能,要求对word文档后台转为pdf,遇到了很多问题,因此记录一下。
网上有很多将Word转换成PDF的方式,这里我试了几种比较简单的方式:POI、、spire和。
1、POI
POI是下的一个Java类库,可以帮助我们实现Java与各种格式文件的互相转换。下面是实现步骤:
引入依赖
org.apache.poi
poi
4.1.2
org.apache.poi
poi-ooxml
4.1.2
com.itextpdf
itextpdf
5.5.13.2
工具类代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfWriter;
public class WordToPdfConverter {
public static void convertToPdf(String inputFilePath, String outputFilePath) {
try {
// 加载Word文档
FileInputStream fis = new FileInputStream(inputFilePath);
XWPFDocument document = new XWPFDocument(fis);
// 创建PDF文档
Document pdfDoc = new Document();
PdfWriter.getInstance(pdfDoc, new FileOutputStream(outputFilePath));
pdfDoc.open();
// 将Word文档内容写入PDF文档
for (XWPFParagraph paragraph : document.getParagraphs()) {
pdfDoc.add(paragraph.createRun().getText());
}
for (XWPFTable table : document.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
pdfDoc.add(cell.getText());
}
}
}
pdfDoc.close();
document.close();
System.out.println("Word文档已成功转换为PDF!");
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String inputFilePath = "input.docx";
String outputFilePath = "output.pdf";
convertToPdf(inputFilePath, outputFilePath);
}
}
POI库在转换过程中无法完全保留Word文档的所有样式。POI库的主要目标是处理Word文档的内容,而不是完全复制其样式。因此,转换后的PDF文件可能会有一些样式差异。如果是比较复杂的Word不建议使用此方式
2、.Words
.Words for Java是一个原生库,为开发人员提供了丰富的功能来创建、编辑和转换 Word、PDF、Web 文档,而无需在系统上安装 Word 环境。该 Java 库是依赖于文档对象模型 (DOM) 的类和方法的集合,使开发人员能够在元素级别直接访问文档的内部工作方式。使用我们的产品,Java 开发人员可以高效地创建复杂的文档并修改其格式、布局和内容。
对于寻求综合工具来简化文档编辑和文档生成任务的开发人员来说,这个原生 Java API 是一个可靠的文档处理解决方案;大规模自动化文档密集型业务流程;减少人工干预、错误和延迟。
官网:
引入依赖(建议将jar包下载下来并上传私服里去)
com.aspose
aspose-words
18.6
jdk16
需要在项目里加入一个.xml,不然生成的pdf会有水印
.xml如下:
Aspose.Total for Java
Aspose.Words for Java
Enterprise
20991231
20991231
8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7
sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
代码如下:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.FontSettings;
import com.aspose.words.SaveFormat;
public static boolean asposeWordToPdf() {
if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
return false;
}
String inPath = "D:\GoogleDownload\ExportWord_230803_032555.docx";
String outputFilePath = "C:\Users\WPC\Desktop\test.pdf";
FileOutputStream os = null;
try {
long old = System.currentTimeMillis();
File file = new File(outputFilePath); // 新建一个空白pdf文档
os = new FileOutputStream(file);
com.aspose.words.Document doc = new Document(inPath); // Address是将要被转化的word文档
//Linux 下使用字体库
// FontSettings fontSettings = new FontSettings();
// fontSettings.setFontsFolder("/usr/share/fonts/windows"+File.separator,true);
// doc.setFontSettings(fontSettings);
doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
// EPUB, XPS, SWF 相互转换
long now = System.currentTimeMillis();
System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
} catch (Exception e) {
e.printStackTrace();
return false;
}finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
public static boolean getLicense() {
boolean result = false;
try {
InputStream is = Test.class.getClassLoader().getResourceAsStream("\license.xml"); // license.xml应放在资源路径下
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
当文档中含有中文字符时,该段代码的执行需要调用操作系统的本地字体库支持,否则所有中文字符都将乱码。
该段代码如果想要在Linux服务器上完美运行,需要给Linux服务器安装中文字体库。可以看最后Java使用Spire.Pdf或-Words实现Word转换Pdf在Linux服务器上的中文乱码问题
3、spire.doc.free
Spire.Doc for Java是一个专业的 Word API,它使 Java 应用程序能够创建、转换、操作和打印 Word文档,而无需依赖 Word。通过使用这个多功能库,开发人员可以轻松处理大量任务,例如插入图像、超链接、 数字签名、书签和水印、设置页眉和页脚、创建表格、设置背景图像以及添加脚注和尾注。此外,Spire.Doc for Java 支持从Word 到 PDF、XPS、Image、EPUB、HTML、TXT、ODT、RTF、、 等文件格式转换。
注意:免费版Free Spire.Doc for Java 仅限于 500 个段落和 25 个表格。在读取或写入文件期间会强制执行此限制。将Word文档转换为PDF和XPS文件时,您只能获取PDF文件的前3页。
官网:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img–39)(img.png)]](/img/)
下载 Spire.Doc for Java 开始免费试用:
引入依赖:
com.e-iceblue
https://repo.e-iceblue.cn/repository/maven-public/
e-iceblue
spire.doc.free
5.2.0
代码如下:
import com.spire.doc.FileFormat;
private static void spireWordToPdf() throws IOException {
//实例化Document类的对象
com.spire.doc.Document doc = new com.spire.doc.Document();
// 下载Word文件
// URL url = new URL("http://xxxx/ExportWord_230724_172956.docx");
// InputStream inputStream = url.openStream();
// doc.loadFromStream(inputStream,FileFormat.Docx);
//加载Word
doc.loadFromFile("D:\GoogleDownload\ExportWord_230803_032555.docx");
//保存为PDF格式
doc.saveToFile("C:\Users\WPC\Desktop\test.pdf", FileFormat.PDF);
}
该段代码如果想要在Linux服务器上完美运行,需要给Linux服务器安装中文字体库。可以看最后Java使用Spire.Pdf或-Words实现Word转换Pdf在Linux服务器上的中文乱码问题
4、
官网:#/
:
是一个跨平台的文档转换库,并且可以在 Linux 上进行 Word 转 PDF 的操作。
它利用 的 APIs 来进行文档转换,因此需要在Linux上安装 / 编辑器。
以下是在Linux环境下执行 Word 转 PDF 的基本步骤:
:使用以下命令安装
sudo apt-get install libreoffice
:使用以下命令安装
sudo yum install libreoffice
引入依赖:
com.documents4j
documents4j-local
1.0.3
com.documents4j
documents4j-transformer-msoffice-word
1.0.3
代码如下:
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
public static void word2pdf() throws IOException {
// 参考:https:blog.csdn.net/ka3p06/article/details/125476270 通过documents4j实现
InputStream docxInputStream = null;
OutputStream outputStream = null;
try {
// 原word地址
// docxInputStream = new FileInputStream("E:\\test2\\word模板.docx");
URL url = new URL("http://xxxx/ExportWord_230724_172956.docx");
docxInputStream = url.openStream();
// 转换后pdf生成地址
outputStream = new FileOutputStream("C:\Users\WPC\Desktop\test.pdf");
IConverter converter = LocalConverter.builder().build();
converter.convert(docxInputStream)
.as(DocumentType.DOCX)
.to(outputStream)
.as(DocumentType.PDF).execute();
// 关闭
converter.shutDown();
// 关闭
outputStream.close();
// 关闭
docxInputStream.close();
} catch (Exception e) {
System.out.println("[documents4J] word转pdf失败:" + e.toString());
} finally {
if (outputStream != null) {
outputStream.close();
}
if (docxInputStream != null) {
docxInputStream.close();
}
}
}
Java使用Spire.Pdf或-Words实现Word转换Pdf在Linux服务器上的中文乱码问题原因分析:
当Word文档中含有中文字符时,不管是使用Spire.Pdf或-Words实现Word转换Pdf,代码的执行都需要调用操作系统的本地字体库支持,否则所有中文字符都将乱码。
在环境下没有问题但是在Linux环境下有问题,说明不是代码或者输入输出流编码的问题,根本原因是两个平台环境的问题。出现乱码说明Linux环境中没有相应的字体以供使用
如果你的代码想要在Linux服务器上完美运行,就需要给Linux服务器安装中文字体库
解决方案:将转换无问题的主机中的字体拷贝到Linux平台下进行安装,重启服务器后转换就不会出现乱码
字体复制到Linux环境并安装
字体库的位置是C:\fonts,这里面包含所有下可用的字体
Linux字体库的位置是 /usr/share/Fonts
在该目录下新建一个目录,比如目录名叫 ,然后将 字体库中你要的字体文件复制到新建的目录下(只需要复制*.ttc,和*.ttf格式的文件)
更改这些字体库的权限
sudo chmod 755 /usr/share/fonts/windows/*
然后进入Linux字体库
cd /usr/share/fonts/windows/
接着根据当前目录下的字体建立scale文件。PS:如果提示找不到这个命令,使用:yum
sudo mkfontscale
接着建立dir文件。PS:如果提示找不到这个命令,使用:yum
sudo mkfontdir
然后运行
sudo fc-cache
最后需要重启一次服务器
如果是环境下
重复上面操作,不过进入的服务器是宿主机
** run -v /usr/share/fonts:/usr/share/fonts *****
启动时共享宿主机的字体库重启项目即可解决乱码问题
本文由博客一文多发平台 发布!
发表回复