admin管理员组文章数量:1130349
拿到本地word路径,和要转为的pdf路径
public static void toPdf(String wordPath) throws IOException {
String pdfPath = wordPath.replace(".docx", ".pdf");
//word转pdf
Word2PdfUtil2.doc2pdf(wordPath, pdfPath);
}
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.5.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
</exclusion>
<exclusion>
<artifactId>commons-lang3</artifactId>
<groupId>org.apachemons</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.5.0</version>
<scope>compile</scope>
</dependency>
这段代码是一个用于将Word文档(.doc或.docx)转换为PDF文件的静态方法。它通过遍历文档中的表格并调整表格宽度以适应页面,最终生成PDF文件。以下是对代码的详细解释及潜在问题的分析:
代码功能解析
1. 方法签名
public static void doc2pdf(String inPath, String outPath)
- 输入:
inPath:输入的Word文档路径。outPath:输出的PDF文件路径。
- 功能:将指定路径的Word文件转换为PDF。
2. 核心逻辑
-
记录初始时间:
long old = System.currentTimeMillis();用于计算转换过程耗时。
-
创建输出文件流:
File file = new File(outPath); FileOutputStream os = new FileOutputStream(file);初始化PDF输出流,若文件路径不存在可能抛出异常(需处理)。
-
加载Word文档:
Document doc = new Document(inPath);使用第三方库(如Aspose.Words)加载Word文档,解析其内容。
-
处理表格:
NodeCollection<Table> tables = doc.getChildNodes(NodeType.TABLE, true); for (Table table : tables) { fitTableToPageWidth(table); }- 获取所有表格:递归搜索文档中的所有表格(
true表示深度遍历)。 - 调整表格宽度:调用
fitTableToPageWidth方法(未提供实现),假设其功能是调整表格宽度以适应PDF页面。
- 获取所有表格:递归搜索文档中的所有表格(
-
保存为PDF:
doc.save(os, SaveFormat.PDF);将处理后的文档以PDF格式保存到输出流。
-
关闭资源与耗时统计:
os.close(); System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");关闭输出流并打印转换耗时。
3. 异常处理
catch (Exception e) {
e.printStackTrace();
}
捕获所有异常并打印堆栈跟踪,但未区分错误类型(如文件不存在、权限问题等)。
潜在问题与改进建议
1. 资源泄漏风险
- 问题:如果
doc.save()抛出异常,os.close()可能不会执行,导致文件句柄未释放。 - 解决:使用
try-with-resources自动关闭资源:try (FileOutputStream os = new FileOutputStream(file)) { // 保存操作 } catch (Exception e) { // 异常处理 }
2. 文件路径验证缺失
- 问题:未检查
inPath或outPath是否存在、是否可读/可写。 - 改进:
File inputFile = new File(inPath); if (!inputFile.exists()) { throw new IllegalArgumentException("输入文件不存在!"); } File outputDir = new File(outPath).getParentFile(); if (!outputDir.exists()) { outputDir.mkdirs(); // 自动创建输出目录 }
3. 表格处理方法的实现依赖
- 问题:
fitTableToPageWidth方法未提供实现,若未正确调整表格宽度,可能导致PDF中表格显示异常。 - 建议:需确保该方法逻辑正确,例如设置表格宽度为页面宽度:
private static void fitTableToPageWidth(Table table) { table.setAllowAutoFit(true); // 允许自动调整 table.setPreferredWidth(PageWidth); // 设置为页面宽度 }
4. 异常处理不足
- 问题:所有异常统一处理,无法区分具体错误(如格式不支持、内存不足等)。
- 改进:
catch (FileNotFoundException e) { System.err.println("输出路径无效或权限不足!"); } catch (IOException e) { System.err.println("文件读写错误!"); } catch (Exception e) { System.err.println("转换失败:" + e.getMessage()); }
5. 第三方库依赖
- 假设:代码依赖Aspose.Words库(
Document和SaveFormat类)。 - 注意:需确认库的版本和许可证,某些库可能需要付费授权。
示例调用
doc2pdf("input.docx", "output.pdf");
- 将
input.docx转换为output.pdf,并调整所有表格宽度以适应页面。
总结
这段代码实现了Word到PDF的基础转换功能,核心逻辑清晰,但存在资源泄漏、异常处理不完善等问题。通过优化资源管理、增强错误处理及验证输入路径,可提升其健壮性。若需处理复杂文档(如图片、样式),可能需要进一步配置转换选项。
public class Word2PdfUtil2 {
public static boolean getLicense() {
boolean result = false;
try {
// license.xml应放在..\WebRoot\WEB-INF\classes路径下
InputStream is = Word2PdfUtil.class.getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static void doc2Img(String inPath, String outPath) throws IOException {
// if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
// return;
// }
try {
// 加载Word文档
Document doc = new Document(inPath);
StyleCollection style = doc.getStyles();
// 获取文档中的所有页面
int pageCount = doc.getPageCount();
// 遍历每个页面
for (int i = 0; i < pageCount; i++) {
// Document extractedPage = doc.extractPages(i, 1);
// extractedPage.setAutomaticallyUpdateStyles(true);
// String path = outPath+"page_" + (i + 1) + ".jpeg";
// extractedPage.save(path, SaveFormat.JPEG);
float height = doc.getPageInfo(i).getHeightInPoints();
float width = doc.getPageInfo(i).getWidthInPoints();
System.err.println(height);
System.err.println(width);
// 创建一个新的空白图片
BufferedImage image = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
// 渲染当前页面到图片
doc.renderToScale(i, graphics, 0, 0, 0.7f);
// doc.renderToSize(i, graphics, 0, 0, width, height);
// 保存图片到文件
ImageIO.write(image, "png", new File(outPath+"page_" + (i + 1) + ".png"));
}
String pathProfile = "";
downloadPdf(pathProfile +"/image/",pathProfile +"/123.pdf");
}catch (Exception e){
System.err.println(e);
}
}
/**
* 得到img字节列表
*
* @param filePath 文件路径
* @return {@link List}<{@link byte[]}>
*/
private static List<byte[]> getImgByteList(String filePath) throws IOException {
// 转换
List<byte[]> imageBytesList = new ArrayList<>();
File folder = new File(filePath);
File[] files = folder.listFiles();
for (File file : files) {
if (file.isFile() && isImage(file)) {
byte[] imageBytes = convertImageToBytes(file);
imageBytesList.add(imageBytes);
}
}
return imageBytesList;
}
private static boolean isImage(File file) {
String fileName = file.getName().toLowerCase();
return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") ||
fileName.endsWith(".png") || fileName.endsWith(".gif") ||
fileName.endsWith(".bmp");
}
private static byte[] convertImageToBytes(File file) throws IOException {
BufferedImage image = ImageIO.read(file);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "png", outputStream);
return outputStream.toByteArray();
}
/**
* 下载
*
* @param imgFilePath img文件路径
* @param filePath 文件路径
* @throws IOException ioexception
*/
private static void downloadPdf( String imgFilePath,String filePath) {
try {
// 1.将本地的图片转成流形式
List<byte[]> imageBytesList = getImgByteList(imgFilePath);
// 2. 生成一页 PDF document
PDDocument document = new PDDocument();
for(int i=0; i<imageBytesList.size(); i++){
byte[] imageBytes = imageBytesList.get(i);
PDImageXObject image = PDImageXObject.createFromByteArray(document, imageBytes, "image");
// 这里是你生成PDF自适应图片大小,不设置会默认为A4
PDRectangle pageSize = new PDRectangle(image.getWidth(), image.getHeight());
PDPage page = new PDPage(pageSize);
document.addPage(page);
// 3.将 图片 添加进PDF document
PDPageContentStream contentStream = new PDPageContentStream(document, page);
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
float imageWidth = image.getWidth();
float imageHeight = image.getHeight();
float scale = Math.min(pageWidth / imageWidth, pageHeight / imageHeight);
float scaledWidth = imageWidth * scale;
float scaledHeight = imageHeight * scale;
float x = (pageWidth - scaledWidth) / 2;
float y = (pageHeight - scaledHeight) / 2;
// 这里是将你的图片填充入pdf页
contentStream.drawImage(image, x, y, scaledWidth, scaledHeight);
contentStream.close();
}
// 4. 保存PDF
File outputFile = new File(filePath);
File parentFolder = outputFile.getParentFile();
if (parentFolder != null && !parentFolder.exists()) {
parentFolder.mkdirs();
}
document.save(outputFile);
document.close();
}catch (Exception e){
}
}
/**
* 从文件读取字节
*
* @param file 文件
* @return {@link byte[]}
* @throws IOException ioexception
*/
private static byte[] readBytesFromFile(File file) throws IOException {
FileInputStream inputStream = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(inputStream);
inputStream.close();
return bytes;
}
public static void fitTableToPageWidth(Table table) {
//Get the page settings from the section where the table occurs, as each section can have different page settings.
Section section = (Section) table.getAncestor(NodeType.SECTION);
//First run simply gets the table size (the widest row). This is used to calculate the ratio below instead of just each row length
//as the last cell in one row could be shorter than the last cell in the other row. This will preserve these different sizes when fitting.
double tableWidth = 0;
for (Row row : table.getRows()) {
double rowWidth = 0;
for (Cell cell : row.getCells()) {
rowWidth += cell.getCellFormat().getWidth();
cell.getCellFormat().setFitText(false);
}
//If this row is larger than previous set this width as the longest row.
if (rowWidth > tableWidth)
{
tableWidth = rowWidth;
}
}
//Calculate the width of the page
double pageWidth = section.getPageSetup().getPageWidth() - (section.getPageSetup().getLeftMargin() + section.getPageSetup().getRightMargin());
//In the second run set each cell in the row proportionally to the width of the page
for(Row row : table.getRows()) {
for(Cell cell : row.getCells())
{
//Calculate the ratio of each cell to the row width and then translate this ratio to the page width.
double cellRatio = cell.getCellFormat().getWidth() / tableWidth;
double width = cell.getCellFormat().getWidth();
int contentLength = cell.getText().length();
if(width<80){
if(contentLength>8){
cell.getCellFormat().setFitText(true);
}
}
cell.getCellFormat().setWidth(cellRatio * pageWidth);
}
}
}
public static void doc2pdf(String inPath, String outPath) {
try {
long old = System.currentTimeMillis();
File file = new File(outPath); // 新建一个空白pdf文档
FileOutputStream os = new FileOutputStream(file);
Document doc = new Document(inPath); // Address是将要被转化的word文档
NodeCollection<Table> tables = doc.getChildNodes(NodeType.TABLE, true);
// 遍历所有表格
for (Table table : tables) {
// 获取表格中的行和单元格
fitTableToPageWidth(table);
}
doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
// EPUB, XPS, SWF 相互转换
long now = System.currentTimeMillis();
System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
拿到本地word路径,和要转为的pdf路径
public static void toPdf(String wordPath) throws IOException {
String pdfPath = wordPath.replace(".docx", ".pdf");
//word转pdf
Word2PdfUtil2.doc2pdf(wordPath, pdfPath);
}
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.5.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
</exclusion>
<exclusion>
<artifactId>commons-lang3</artifactId>
<groupId>org.apachemons</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.5.0</version>
<scope>compile</scope>
</dependency>
这段代码是一个用于将Word文档(.doc或.docx)转换为PDF文件的静态方法。它通过遍历文档中的表格并调整表格宽度以适应页面,最终生成PDF文件。以下是对代码的详细解释及潜在问题的分析:
代码功能解析
1. 方法签名
public static void doc2pdf(String inPath, String outPath)
- 输入:
inPath:输入的Word文档路径。outPath:输出的PDF文件路径。
- 功能:将指定路径的Word文件转换为PDF。
2. 核心逻辑
-
记录初始时间:
long old = System.currentTimeMillis();用于计算转换过程耗时。
-
创建输出文件流:
File file = new File(outPath); FileOutputStream os = new FileOutputStream(file);初始化PDF输出流,若文件路径不存在可能抛出异常(需处理)。
-
加载Word文档:
Document doc = new Document(inPath);使用第三方库(如Aspose.Words)加载Word文档,解析其内容。
-
处理表格:
NodeCollection<Table> tables = doc.getChildNodes(NodeType.TABLE, true); for (Table table : tables) { fitTableToPageWidth(table); }- 获取所有表格:递归搜索文档中的所有表格(
true表示深度遍历)。 - 调整表格宽度:调用
fitTableToPageWidth方法(未提供实现),假设其功能是调整表格宽度以适应PDF页面。
- 获取所有表格:递归搜索文档中的所有表格(
-
保存为PDF:
doc.save(os, SaveFormat.PDF);将处理后的文档以PDF格式保存到输出流。
-
关闭资源与耗时统计:
os.close(); System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");关闭输出流并打印转换耗时。
3. 异常处理
catch (Exception e) {
e.printStackTrace();
}
捕获所有异常并打印堆栈跟踪,但未区分错误类型(如文件不存在、权限问题等)。
潜在问题与改进建议
1. 资源泄漏风险
- 问题:如果
doc.save()抛出异常,os.close()可能不会执行,导致文件句柄未释放。 - 解决:使用
try-with-resources自动关闭资源:try (FileOutputStream os = new FileOutputStream(file)) { // 保存操作 } catch (Exception e) { // 异常处理 }
2. 文件路径验证缺失
- 问题:未检查
inPath或outPath是否存在、是否可读/可写。 - 改进:
File inputFile = new File(inPath); if (!inputFile.exists()) { throw new IllegalArgumentException("输入文件不存在!"); } File outputDir = new File(outPath).getParentFile(); if (!outputDir.exists()) { outputDir.mkdirs(); // 自动创建输出目录 }
3. 表格处理方法的实现依赖
- 问题:
fitTableToPageWidth方法未提供实现,若未正确调整表格宽度,可能导致PDF中表格显示异常。 - 建议:需确保该方法逻辑正确,例如设置表格宽度为页面宽度:
private static void fitTableToPageWidth(Table table) { table.setAllowAutoFit(true); // 允许自动调整 table.setPreferredWidth(PageWidth); // 设置为页面宽度 }
4. 异常处理不足
- 问题:所有异常统一处理,无法区分具体错误(如格式不支持、内存不足等)。
- 改进:
catch (FileNotFoundException e) { System.err.println("输出路径无效或权限不足!"); } catch (IOException e) { System.err.println("文件读写错误!"); } catch (Exception e) { System.err.println("转换失败:" + e.getMessage()); }
5. 第三方库依赖
- 假设:代码依赖Aspose.Words库(
Document和SaveFormat类)。 - 注意:需确认库的版本和许可证,某些库可能需要付费授权。
示例调用
doc2pdf("input.docx", "output.pdf");
- 将
input.docx转换为output.pdf,并调整所有表格宽度以适应页面。
总结
这段代码实现了Word到PDF的基础转换功能,核心逻辑清晰,但存在资源泄漏、异常处理不完善等问题。通过优化资源管理、增强错误处理及验证输入路径,可提升其健壮性。若需处理复杂文档(如图片、样式),可能需要进一步配置转换选项。
public class Word2PdfUtil2 {
public static boolean getLicense() {
boolean result = false;
try {
// license.xml应放在..\WebRoot\WEB-INF\classes路径下
InputStream is = Word2PdfUtil.class.getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static void doc2Img(String inPath, String outPath) throws IOException {
// if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
// return;
// }
try {
// 加载Word文档
Document doc = new Document(inPath);
StyleCollection style = doc.getStyles();
// 获取文档中的所有页面
int pageCount = doc.getPageCount();
// 遍历每个页面
for (int i = 0; i < pageCount; i++) {
// Document extractedPage = doc.extractPages(i, 1);
// extractedPage.setAutomaticallyUpdateStyles(true);
// String path = outPath+"page_" + (i + 1) + ".jpeg";
// extractedPage.save(path, SaveFormat.JPEG);
float height = doc.getPageInfo(i).getHeightInPoints();
float width = doc.getPageInfo(i).getWidthInPoints();
System.err.println(height);
System.err.println(width);
// 创建一个新的空白图片
BufferedImage image = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
// 渲染当前页面到图片
doc.renderToScale(i, graphics, 0, 0, 0.7f);
// doc.renderToSize(i, graphics, 0, 0, width, height);
// 保存图片到文件
ImageIO.write(image, "png", new File(outPath+"page_" + (i + 1) + ".png"));
}
String pathProfile = "";
downloadPdf(pathProfile +"/image/",pathProfile +"/123.pdf");
}catch (Exception e){
System.err.println(e);
}
}
/**
* 得到img字节列表
*
* @param filePath 文件路径
* @return {@link List}<{@link byte[]}>
*/
private static List<byte[]> getImgByteList(String filePath) throws IOException {
// 转换
List<byte[]> imageBytesList = new ArrayList<>();
File folder = new File(filePath);
File[] files = folder.listFiles();
for (File file : files) {
if (file.isFile() && isImage(file)) {
byte[] imageBytes = convertImageToBytes(file);
imageBytesList.add(imageBytes);
}
}
return imageBytesList;
}
private static boolean isImage(File file) {
String fileName = file.getName().toLowerCase();
return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") ||
fileName.endsWith(".png") || fileName.endsWith(".gif") ||
fileName.endsWith(".bmp");
}
private static byte[] convertImageToBytes(File file) throws IOException {
BufferedImage image = ImageIO.read(file);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "png", outputStream);
return outputStream.toByteArray();
}
/**
* 下载
*
* @param imgFilePath img文件路径
* @param filePath 文件路径
* @throws IOException ioexception
*/
private static void downloadPdf( String imgFilePath,String filePath) {
try {
// 1.将本地的图片转成流形式
List<byte[]> imageBytesList = getImgByteList(imgFilePath);
// 2. 生成一页 PDF document
PDDocument document = new PDDocument();
for(int i=0; i<imageBytesList.size(); i++){
byte[] imageBytes = imageBytesList.get(i);
PDImageXObject image = PDImageXObject.createFromByteArray(document, imageBytes, "image");
// 这里是你生成PDF自适应图片大小,不设置会默认为A4
PDRectangle pageSize = new PDRectangle(image.getWidth(), image.getHeight());
PDPage page = new PDPage(pageSize);
document.addPage(page);
// 3.将 图片 添加进PDF document
PDPageContentStream contentStream = new PDPageContentStream(document, page);
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
float imageWidth = image.getWidth();
float imageHeight = image.getHeight();
float scale = Math.min(pageWidth / imageWidth, pageHeight / imageHeight);
float scaledWidth = imageWidth * scale;
float scaledHeight = imageHeight * scale;
float x = (pageWidth - scaledWidth) / 2;
float y = (pageHeight - scaledHeight) / 2;
// 这里是将你的图片填充入pdf页
contentStream.drawImage(image, x, y, scaledWidth, scaledHeight);
contentStream.close();
}
// 4. 保存PDF
File outputFile = new File(filePath);
File parentFolder = outputFile.getParentFile();
if (parentFolder != null && !parentFolder.exists()) {
parentFolder.mkdirs();
}
document.save(outputFile);
document.close();
}catch (Exception e){
}
}
/**
* 从文件读取字节
*
* @param file 文件
* @return {@link byte[]}
* @throws IOException ioexception
*/
private static byte[] readBytesFromFile(File file) throws IOException {
FileInputStream inputStream = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(inputStream);
inputStream.close();
return bytes;
}
public static void fitTableToPageWidth(Table table) {
//Get the page settings from the section where the table occurs, as each section can have different page settings.
Section section = (Section) table.getAncestor(NodeType.SECTION);
//First run simply gets the table size (the widest row). This is used to calculate the ratio below instead of just each row length
//as the last cell in one row could be shorter than the last cell in the other row. This will preserve these different sizes when fitting.
double tableWidth = 0;
for (Row row : table.getRows()) {
double rowWidth = 0;
for (Cell cell : row.getCells()) {
rowWidth += cell.getCellFormat().getWidth();
cell.getCellFormat().setFitText(false);
}
//If this row is larger than previous set this width as the longest row.
if (rowWidth > tableWidth)
{
tableWidth = rowWidth;
}
}
//Calculate the width of the page
double pageWidth = section.getPageSetup().getPageWidth() - (section.getPageSetup().getLeftMargin() + section.getPageSetup().getRightMargin());
//In the second run set each cell in the row proportionally to the width of the page
for(Row row : table.getRows()) {
for(Cell cell : row.getCells())
{
//Calculate the ratio of each cell to the row width and then translate this ratio to the page width.
double cellRatio = cell.getCellFormat().getWidth() / tableWidth;
double width = cell.getCellFormat().getWidth();
int contentLength = cell.getText().length();
if(width<80){
if(contentLength>8){
cell.getCellFormat().setFitText(true);
}
}
cell.getCellFormat().setWidth(cellRatio * pageWidth);
}
}
}
public static void doc2pdf(String inPath, String outPath) {
try {
long old = System.currentTimeMillis();
File file = new File(outPath); // 新建一个空白pdf文档
FileOutputStream os = new FileOutputStream(file);
Document doc = new Document(inPath); // Address是将要被转化的word文档
NodeCollection<Table> tables = doc.getChildNodes(NodeType.TABLE, true);
// 遍历所有表格
for (Table table : tables) {
// 获取表格中的行和单元格
fitTableToPageWidth(table);
}
doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
// EPUB, XPS, SWF 相互转换
long now = System.currentTimeMillis();
System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
版权声明:本文标题:java实现word转pdf 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/jiaocheng/1763671539a2953171.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论