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

前提:

面对各种文件转换pdf格式,我下面写的都是一些方法,其中每个方法都以流的方式进行参数的传递。
通过猿友的帮忙,修改了部分jar包,解决excel转换pdf导致的水印问题~,通过配置log4j2.xml 解决日志报错问题
源码链接:https://pan.baidu.com/s/1twLNvNE-e0AEa5EVetyOFA
提取码:asdf
jar包 例如com.aspose的包在项目的myjar目录中,需要手动导入。其他的jar包,例如itextpdf可通过依赖直接导入
(上传的项目代码里面ppt/pptx还没有更新代码,主要是修复ppt、pptx转pdf的汉字乱码问题,最新的代码请参考文章,文章内容是最新的)
java : word,excel,img,ppt各种文档转换pdf格式以流方式_第1张图片


```java
    
        org.apache.poi
        poi
        4.1.2
    

    
        org.apache.poi
        poi-ooxml
        4.1.2
    
    
        org.apache.poi
        poi-scratchpad
        4.1.2
    


    
        com.itextpdf
        itextpdf
        5.4.3
    

    
        com.itextpdf
        itext-asian
        5.2.0
    

    
        org.docx4j
        docx4j
        3.2.2
    

   
    
    
        org.apache.logging.log4j
        log4j-api
        2.17.1
    
    
    
        org.apache.logging.log4j
        log4j-core
        2.11.1
    


    

    
    
        org.apache.xmlbeans
        xmlbeans
        5.0.3
    
    
        org.apache.poi
        poi-ooxml-schemas
        4.1.2
    
    
        org.apache.commons
        commons-compress
        1.19
    
    
        org.apache.commons
        commons-collections4
        4.1
    

    
        com.zaxxer
        SparseBitSet
        1.2
    
    
        cn.hutool
        hutool-all
        5.6.0
    

        
    
        
        
        
    

# 工具类主体:

```java
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 final class PdfConverUtil {

//  这里放下面的方法
xxxx...

}

img(png)转换pdf:

关于图片转换pdf的像素问题,可以设置转换pdf的大小来控制

    /**
     * @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;
    }

word(doc/docx)转换pdf:

该方法运行可能出现警告:(可忽略,不影响pdf文件生成!)
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(…) returned error code 5.
解决方法: http://t.csdn.cn/zQn6C

    /**
     * @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 = "Aspose.Total for JavaAspose.Words for JavaEnterprise20991231209912318bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=";
            ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

excel(xlsx)转换pdf:

excel中的 Workbook 使用的是 com.aspose.cells 包下的。注意!!!
至于sheet相关,分页问题,可以据情况修改方法printSheetPage()和autoDraw()

     /**
     * @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 = "Aspose.Total for JavaAspose.Words for JavaEnterprise20991231209912318bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=";
            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;
    }

ppt(ppt/pptx)转换pdf:

ppt和pptx使用的Document类是 com.itextpdf.text包下面,注意!由于ppt和pptx的编码格式不一样,所以单独写了针对ppt 和 pptx 的转换

    /**
     * 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;
    }

测试

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

/**
 * 功能说明:
 * 开发人员: zhouyangyang
 * 开发时间: 2022/6/28 
* 功能描述: 写明作用,调用方式,使用场景,以及特殊情况
*/
public class Test { public static void main(String[] args) { // imgae to pdf try { FileInputStream inputStream = new FileInputStream("D:\\testConvert\\银行卡.jpg"); FileOutputStream byteArrayOutputStream = new FileOutputStream("D:\\testConvert\\银行卡.pdf"); PdfConverUtil.imgToPdf(inputStream, byteArrayOutputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } // doc/docx to pdf try { FileInputStream inputStream = new FileInputStream("D:\\testConvert\\zyydocx.docx"); FileOutputStream byteArrayOutputStream = new FileOutputStream("D:\\testConvert\\zyydocx.pdf"); PdfConverUtil.wordTopdfByAspose(inputStream, byteArrayOutputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } // execl to pdf try { FileInputStream inputStream = new FileInputStream("D:\\testConvert\\zyyexcel.xls"); FileOutputStream byteArrayOutputStream = new FileOutputStream("D:\\testConvert\\zyyexcel.pdf"); PdfConverUtil.excelToPdf(inputStream, byteArrayOutputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } // ppt tp pdf try { FileInputStream inputStream = new FileInputStream("D:\\testConvert\\zyy123ppt.ppt"); FileOutputStream byteArrayOutputStream = new FileOutputStream("D:\\testConvert\\zyy123pptnew.pdf"); PdfConverUtil.pptToPdf(inputStream, byteArrayOutputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } // pptx to pdf try { FileInputStream inputStream = new FileInputStream("D:\\testConvert\\zyypptx.pptx"); FileOutputStream byteArrayOutputStream = new FileOutputStream("D:\\testConvert\\zyypptxnew.pdf"); PdfConverUtil.pptxToPdf(inputStream, byteArrayOutputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } } }

如图:
java : word,excel,img,ppt各种文档转换pdf格式以流方式_第2张图片

java : word,excel,img,ppt各种文档转换pdf格式以流方式_第3张图片
存在的问题
1.中文乱码(已解决),具体可参考
// 设置字体, 解决中文乱码
for (XSLFShape shape : slide.getShapes()) {
if (shape instanceof XSLFTextShape) {
XSLFTextShape textShape = (XSLFTextShape) shape;

  1. 日志报错(已解决), 错误提示 是要配置引入log4j2
    2.1 导入两个依赖
        <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>

2.2 在classpath路径下添加log4j2.xml配置文件
java : word,excel,img,ppt各种文档转换pdf格式以流方式_第4张图片

<?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>
  1. 目前ppt/pptx若存在图片,则需要注释掉以下代码,否则转换pdf异常,关于如何解决,后续有时间再更新
      // 设置字体, 解决中文乱码
                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("宋体");
                            }
                        }
                    }
                }

你可能感兴趣的:(poi,itext,excel,java)