这段时间的工作中碰到两个需求,一个是将word转换为pdf,一个是将多个pdf合并为同一个pdf,参考了网上许多大佬的文章,最终记录一下我的实现方案。
word转pdf
使用的jar包:aspose-words-15.8.0-jdk16.jar
使用到的xml文件:License.xml
xml文件内容
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>
使用到的方法
public static boolean getLicense() {
boolean result = false;
try {
File file = new File("src/main/java/com/ApiPro/common/utils/License.xml"); // 新建一个空白pdf文档
InputStream is = new FileInputStream(file); // license.xml找个路径放即可。
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* @param wordPath 需要被转换的word全路径带文件名
* @param pdfPath 转换之后pdf的全路径带文件名
*/
public static void doc2pdf(String wordPath, String pdfPath) {
if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
return;
}
try {
long old = System.currentTimeMillis();
File file = new File(pdfPath); //新建一个pdf文档
FileOutputStream os = new FileOutputStream(file);
Document doc = new Document(wordPath); //Address是将要被转化的word文档
//需要被替换的字体
String FONT_STYLE = "simsun";
ArrayList<Run> runs = getRunsByStyleName(doc, FONT_STYLE);
for (Run run : runs) {
run.setText(replaceWithBlank(run.getText()));
}
doc.save(os, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
long now = System.currentTimeMillis();
os.close();
System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时
} catch (Exception e) {
e.printStackTrace();
}
}
多个pdf合并
合并pdf使用的是spire.pdf,使用方式可以参照官方文档:
https://www.e-iceblue.cn/licensing/install-spirepdf-for-java-from-maven-repository.html
不过合并之后生成的pdf文档第一页的左上角会有水印,网上搜到的去除水印的办法大多都是删除掉带有水印的第一页空页,类似下面这种:
PdfDocument pdfDocument = new PdfDocument();
pdfDocument.Pages.Add();
pdfDocument.Pages.RemoveAt(0);
但是不知什么原因我测试并不能用,所以我用这个思路使用其他jar包中的方法删除掉合成进pdf中的第一页空页最终完成,jar包引用以及代码如下:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
/**
* 截取pdfFile的第from页至第end页,组成一个新的文件名
* @param pdfFile 需要分割的PDF
* @param savepath 新PDF
* @param from 起始页
* @param end 结束页
*/
public static void splitPDFFile(String respdfFile,
String savepath, int from, int end) throws DocumentException {
com.itextpdf.text.Document document = null;
PdfCopy copy = null;
try {
PdfReader reader = new PdfReader(respdfFile);
int n = reader.getNumberOfPages();
if(end==0){
end = n;
}
ArrayList<String> savepaths = new ArrayList<String>();
String staticpath = respdfFile.substring(0, respdfFile.lastIndexOf("\\")+1);
//String savepath = staticpath+ newFile;
savepaths.add(savepath);
document = new com.itextpdf.text.Document(reader.getPageSize(1));
copy = new PdfCopy(document, new FileOutputStream(savepaths.get(0)));
document.open();
for(int j=from; j<=end; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
document.close();
} catch (IOException e) {
e.printStackTrace();
} catch(DocumentException e) {
e.printStackTrace();
}
}
/**
* 支持.docx
* 多个word转pdf后合并为一个pdf
* 合并pdf为spire.pdf 方式 (去除水印)
* @param oldFilePath 旧文件路径
* @param newFilePath 新生成的文件路径
* @param wordFileName word文档名(不加后缀)
* @param mergePdfFileName 最后生成的pdf文件名(不加后缀)
* @return 生成的pdf路径名
*/
public static String wordToPdfMerge(String oldFilePath, String newFilePath, List<String> wordFileName, String mergePdfFileName){
String word = ".docx";
String pdf = ".pdf";
//word转pdf
for (String name : wordFileName) {
PdfUtils.doc2pdf(oldFilePath + name + word, newFilePath + name + pdf);
}
List<InputStream> files = new ArrayList<>();
for (String name : wordFileName) {
System.err.println("pdf地址:" + newFilePath + name + pdf);
FileInputStream stream = null;
try {
stream = new FileInputStream(new File(newFilePath + name + pdf));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
files.add(stream);
}
InputStream[] streams = new FileInputStream[files.size()];
files.toArray(streams);
//合并PDF文档
System.err.println("开始合并pdf文档,长度为:" + streams.length);
PdfDocumentBase doc = PdfDocument.mergeFiles(streams);
//保存文档
String MergePdfPath = newFilePath + mergePdfFileName;
doc.save(MergePdfPath + "old" + pdf);
doc.close();
PdfReader pdfReader = new PdfReader(new FileInputStream(MergePdfPath + "old" + pdf));
int pages = pdfReader.getNumberOfPages();
System.err.println("pdf页数:" + pages);
//删除文档第一页
try {
PdfUtils.splitPDFFile(MergePdfPath + "old" + pdf
, MergePdfPath + pdf
,2
,pages
);
} catch (DocumentException e) {
e.printStackTrace();
}
return MergePdfPath + pdf;
}
---注意在调用合并pdf的方法时要在需要合并的文件前加一个只有一页空的或者任意内容的word文档用于去除水印。