文件转PDF

参考博客:java : word,excel,img,ppt各种文档转换pdf格式以流方式

环境依赖配置

环境核心依赖配置

外部核心jar包导入

<!--核心依赖-->
<!-- https://mvnrepository.com/artifact/com.aspose.cells/aspose-cells-jdk16 -->
<dependency>
<groupId>com.aspose.cells</groupId>
<artifactId>aspose-cells-jdk16</artifactId>
<version>8.1.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/aspose-cells-21.8.cracked.jar</systemPath>
</dependency>

<!-- https://mvnrepository.com/artifact/com.aspose/aspose-words -->
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>14.7.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar</systemPath>
</dependency>

父类pom文件修改

增加配置项

<includeSystemScope>true</includeSystemScope>

完整配置

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
<!--包含SystemScope文件(2023.07.06)-->
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>

环境其他依赖配置

pom文件增加配置

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>4.1.2</version>
</dependency>


<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.3</version>
</dependency>

<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>

<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>3.2.2</version>
</dependency>


<!-- 出现日志问题,请添加下面log4j-api依赖 和 log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>

<!-- 下面的依赖是为了报其他错误的 -->
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>5.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>

<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>SparseBitSet</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.0</version>
</dependency>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>

日志报错问题解决

备注:此处pom依赖在上文中pom的配置文件已包括

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>

log4j2.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5p] %d %c - %m%n" />
</Console>
<File name="File" fileName="dist/my.log">
<PatternLayout pattern="%m%n" />
</File>
</Appenders>

<Loggers>
<Logger name="mh.sample2.Log4jTest2" level="INFO">
<AppenderRef ref="File" />
</Logger>
<Root level="INFO">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>

启动运行

工具类代码

备注:ppt暂时有部分问题

package com.ruoyi.doc;

import com.aspose.words.*;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.xslf.usermodel.*;

import java.awt.*;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

public class PdfConverUtil {

/**
* @param inputStream 源文件输入流
* @param outputStream pdf文件输出流
**/
public static boolean imgToPdf(InputStream inputStream, OutputStream outputStream) {

Document document = null;

try {

// 创建文档,设置PDF页面的大小 A2-A9, 个人觉得A3最合适
document = new Document(PageSize.A3, 20, 20, 20, 20);

// 新建pdf文档,具体逻辑看.getInstance方法
PdfWriter.getInstance(document, outputStream);

document.open();
document.newPage();

// 将文件流转换为字节流,便于格式转换
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int length = 0 ;
while (-1 != (length = bufferedInputStream.read(bytes))) {
byteArrayOutputStream.write(bytes, 0, length);
}

// 处理img图片
Image image = Image.getInstance(byteArrayOutputStream.toByteArray());

float height = image.getHeight();
float width = image.getWidth();

float percent = 0.0f;
// 设置像素或者长宽高,将会影响图片的清晰度,因为只是对图片放大或缩小
if (height > width) {
// A4 - A9
percent = PageSize.A6.getHeight() / height * 100;
} else {
percent = PageSize.A6.getWidth() / width * 100;
}

image.setAlignment(Image.MIDDLE);
image.scalePercent(percent);

// 将图片放入文档中,完成pdf转换
document.add(image);
System.out.println("image转换完毕");
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (document != null) {
document.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}

return true;
}

/**
* @param inputStream 源文件输入流
* @param outputStream pdf文件输出流
**/
public static boolean wordTopdfByAspose(InputStream inputStream, OutputStream outputStream) {

// 验证License 若不验证则转化出的pdf文档会有水印产生
if (!getLicense()) {
return false;
}
try {
// 将源文件保存在com.aspose.words.Document中,具体的转换格式依靠里面的save方法
com.aspose.words.Document doc = new com.aspose.words.Document(inputStream);

// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,EPUB, XPS, SWF 相互转换
doc.save(outputStream, SaveFormat.PDF);

System.out.println("word转换完毕");
} catch (Exception e) {
e.printStackTrace();
return false;
}finally {
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}

// 官方文档的要求 无需理会
public static boolean getLicense() {
boolean result = false;
try {
String s = "<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>";
ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}


/**
* @param inputStream 源文件输入流
* @param outputStream pdf文件输出流
**/
public static boolean excelToPdf(InputStream inputStream, OutputStream outputStream) {
// 验证License 若不验证则转化出的pdf文档会有水印产生
if (!getExeclLicense()) {
return false;
}
try {
com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(inputStream);// 原始excel路径

com.aspose.cells.PdfSaveOptions pdfSaveOptions = new com.aspose.cells.PdfSaveOptions();
pdfSaveOptions.setOnePagePerSheet(false);


int[] autoDrawSheets={3};
//当excel中对应的sheet页宽度太大时,在PDF中会拆断并分页。此处等比缩放。
autoDraw(wb,autoDrawSheets);

int[] showSheets={0};
//隐藏workbook中不需要的sheet页。
printSheetPage(wb,showSheets);
wb.save(outputStream, pdfSaveOptions);
outputStream.flush();
outputStream.close();
System.out.println("excel转换完毕");
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}


/**
* 设置打印的sheet 自动拉伸比例
* @param wb
* @param page 自动拉伸的页的sheet数组
*/
public static void autoDraw(com.aspose.cells.Workbook wb,int[] page){
if(null!=page&&page.length>0){
for (int i = 0; i < page.length; i++) {
wb.getWorksheets().get(i).getHorizontalPageBreaks().clear();
wb.getWorksheets().get(i).getVerticalPageBreaks().clear();
}
}
}

/**
* 隐藏workbook中不需要的sheet页。
*
* @param wb
* @param page 显示页的sheet数组
*/
public static void printSheetPage(com.aspose.cells.Workbook wb, int[] page) {
for (int i = 1; i < wb.getWorksheets().getCount(); i++) {
wb.getWorksheets().get(i).setVisible(false);
}
if (null == page || page.length == 0) {
wb.getWorksheets().get(0).setVisible(true);
} else {
for (int i = 0; i < page.length; i++) {
wb.getWorksheets().get(i).setVisible(true);
}
}
}

public static boolean getExeclLicense() {
boolean result = false;
try {
String s = "<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>";
ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
com.aspose.cells.License aposeLic = new com.aspose.cells.License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}


/**
* pptToPdf
* @param inputStream
* @param outputStream
* @return
*/
public static boolean pptToPdf(InputStream inputStream, OutputStream outputStream) {

Document document = null;
HSLFSlideShow hslfSlideShow = null;
PdfWriter pdfWriter = null;

try {
hslfSlideShow = new HSLFSlideShow(inputStream);

// 获取ppt文件页面
Dimension dimension = hslfSlideShow.getPageSize();

document = new Document();

// pdfWriter实例
pdfWriter = PdfWriter.getInstance(document, outputStream);

document.open();

PdfPTable pdfPTable = new PdfPTable(1);

List<HSLFSlide> hslfSlideList = hslfSlideShow.getSlides();

for (int i=0; i < hslfSlideList.size(); i++) {
HSLFSlide hslfSlide = hslfSlideList.get(i);
// 设置字体, 解决中文乱码
for (HSLFShape shape : hslfSlide.getShapes()) {
if (shape instanceof HSLFTextShape) {
HSLFTextShape textShape = (HSLFTextShape) shape;
for (HSLFTextParagraph textParagraph : textShape.getTextParagraphs()) {
for (HSLFTextRun textRun : textParagraph.getTextRuns()) {
textRun.setFontFamily("宋体");
}
}
}
}
BufferedImage bufferedImage = new BufferedImage((int)dimension.getWidth(), (int)dimension.getHeight(), BufferedImage.TYPE_INT_RGB);

Graphics2D graphics2d = bufferedImage.createGraphics();

graphics2d.setPaint(Color.white);
graphics2d.setFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 12));

hslfSlide.draw(graphics2d);

graphics2d.dispose();

Image image = Image.getInstance(bufferedImage, null);
image.scalePercent(50f);

// 写入单元格
pdfPTable.addCell(new PdfPCell(image, true));
document.add(image);

}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (document != null) {
document.close();
}
if (pdfWriter != null) {
pdfWriter.close();
}
}
System.out.println("ppt转换完毕");
return true;
}

/**
* pptxToPdf
* @param inputStream
* @param outputStream
* @return
*/
public static boolean pptxToPdf(InputStream inputStream, OutputStream outputStream) {

Document document = null;

XMLSlideShow slideShow = null;

PdfWriter pdfWriter = null;

try {

slideShow = new XMLSlideShow(inputStream);

Dimension dimension = slideShow.getPageSize();

document = new Document();

pdfWriter = PdfWriter.getInstance(document, outputStream);

document.open();

PdfPTable pdfPTable = new PdfPTable(1);

List<XSLFSlide> slideList = slideShow.getSlides();

for (int i = 0, row = slideList.size(); i < row; i++) {

XSLFSlide slide = slideList.get(i);

// 设置字体, 解决中文乱码
for (XSLFShape shape : slide.getShapes()) {
if (shape instanceof XSLFTextShape) {
XSLFTextShape textShape = (XSLFTextShape) shape;

for (XSLFTextParagraph textParagraph : textShape.getTextParagraphs()) {
for (XSLFTextRun textRun : textParagraph.getTextRuns()) {
textRun.setFontFamily("宋体");
}
}
}
}

BufferedImage bufferedImage = new BufferedImage((int)dimension.getWidth(), (int)dimension.getHeight(), BufferedImage.TYPE_INT_RGB);

Graphics2D graphics2d = bufferedImage.createGraphics();

graphics2d.setPaint(Color.white);
graphics2d.setFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 12));

slide.draw(graphics2d);

graphics2d.dispose();

Image image = Image.getInstance(bufferedImage, null);
image.scalePercent(50f);

// 写入单元格
pdfPTable.addCell(new PdfPCell(image, true));
document.add(image);
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (document != null) {
document.close();
}
if (pdfWriter != null) {
pdfWriter.close();
}
}
System.out.println("pptx转换完毕");
return true;
}


}

测试类代码

package com.ruoyi.doc;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Test {

public static void main(String[] args) {
// imgae to pdf
try {
FileInputStream inputStream = new FileInputStream("/Users/ordinary/Downloads/Test.jpg");
FileOutputStream byteArrayOutputStream = new FileOutputStream("/Users/ordinary/Downloads/TestJPG.pdf");
PdfConverUtil.imgToPdf(inputStream, byteArrayOutputStream);

} catch (FileNotFoundException e) {
e.printStackTrace();
}

// doc/docx to pdf
try {
FileInputStream inputStream = new FileInputStream("/Users/ordinary/Downloads/Test.docx");
FileOutputStream byteArrayOutputStream = new FileOutputStream("/Users/ordinary/Downloads/TestDOCX.pdf");
PdfConverUtil.wordTopdfByAspose(inputStream, byteArrayOutputStream);

} catch (FileNotFoundException e) {
e.printStackTrace();
}

// execl to pdf
try {
FileInputStream inputStream = new FileInputStream("/Users/ordinary/Downloads/Test.xlsx");
FileOutputStream byteArrayOutputStream = new FileOutputStream("/Users/ordinary/Downloads/TestXLSX.pdf");
PdfConverUtil.excelToPdf(inputStream, byteArrayOutputStream);

} catch (FileNotFoundException e) {
e.printStackTrace();
}

// ppt tp pdf
/*try {
FileInputStream inputStream = new FileInputStream("/Users/ordinary/Downloads/Test.ppt");
FileOutputStream byteArrayOutputStream = new FileOutputStream("/Users/ordinary/Downloads/TestPPT.pdf");
PdfConverUtil.pptToPdf(inputStream, byteArrayOutputStream);

} catch (FileNotFoundException e) {
e.printStackTrace();
}*/

// pptx to pdf
/*try {
FileInputStream inputStream = new FileInputStream("/Users/ordinary/Downloads/Test.pptx");
FileOutputStream byteArrayOutputStream = new FileOutputStream("/Users/ordinary/Downloads/TestPPTX.pdf");
PdfConverUtil.pptxToPdf(inputStream, byteArrayOutputStream);

} catch (FileNotFoundException e) {
e.printStackTrace();
}*/
}

}

PDF加水印

参考博客:java生成pdf并加水印,通过wkhtmltopdf实现

看:给pdf的每一页都加上文字水印和页码章节

参考博客:Java实现pdf文件添加水印,铺满全页