Java中PDF的轉(zhuǎn)換(圖片)與展示

解決的問題

有些時(shí)候我們需要在項(xiàng)目中展示PDF,但是直接在瀏覽器中加入PDF展示的插件,存在兼容性問題,某些瀏覽器顯示效果不理想,所以我們可以將PDF轉(zhuǎn)為圖片,然后已圖片的方式展示,效果很好。

那么怎么將PDF轉(zhuǎn)為圖片呢?有兩種方式:

產(chǎn)品 特點(diǎn)
Apache 的 PDF box 免費(fèi);速度稍慢一點(diǎn),但可以接受
E-iceblue 的 Spire.PDF for Java 轉(zhuǎn)換效果很好;速度快;功能強(qiáng)大,支持轉(zhuǎn)多種格式;收費(fèi)

Spire.PDF for Java 的轉(zhuǎn)換效果很好,但是如果不購(gòu)買,轉(zhuǎn)換過后會(huì)添加一些水印文字

參考鏈接:https://www.cnblogs.com/Yesi/p/11233238.html

PDF Box的使用

<dependency>
    <groupId>net.sf.cssbox</groupId>
    <artifactId>pdf2dom</artifactId>
    <version>1.7</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.12</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox-tools</artifactId>
    <version>2.0.12</version>
</dependency>

多頁(yè)P(yáng)DF生成多張圖片

新建一個(gè) PdfUtil 工具類

public class PdfUtil {

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PdfUtil.class);

    /***
     * PDF文件轉(zhuǎn)PNG圖片,全部頁(yè)數(shù)
     *
     * @param pdfFilePath pdf完整路徑
     * @param dpi dpi越大轉(zhuǎn)換后越清晰,相對(duì)轉(zhuǎn)換速度越慢
     */
    public static void pdf2Image(String pdfFilePath, int dpi) {
        File file = new File(pdfFilePath);
        PDDocument pdDocument;
        try {
            String imgPdfPath = file.getParent();
            int dot = file.getName().lastIndexOf('.');
            // 獲取圖片文件名
            String imagePdfName = file.getName().substring(0, dot);

            pdDocument = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(pdDocument);
            /* dpi越大轉(zhuǎn)換后越清晰,相對(duì)轉(zhuǎn)換速度越慢 */
            PdfReader reader = new PdfReader(pdfFilePath);
            int pages = reader.getNumberOfPages();
            StringBuffer imgFilePath;
            for (int i = 0; i < pages; i++) {
                String imgFilePathPrefix = imgPdfPath + File.separator + imagePdfName;
                imgFilePath = new StringBuffer();
                imgFilePath.append(imgFilePathPrefix);
                imgFilePath.append("_");
                imgFilePath.append((i + 1));
                imgFilePath.append(".png");
                File dstFile = new File(imgFilePath.toString());
                BufferedImage image = renderer.renderImageWithDPI(i, dpi);
                ImageIO.write(image, "png", dstFile);
            }
            log.info("PDF文檔轉(zhuǎn)PNG圖片成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

多頁(yè)P(yáng)DF組合成一張圖片

public class PdfUtil {

    public static final int DEFAULT_DPI = 150;

    /**
     * pdf轉(zhuǎn)圖片
     * 多頁(yè)P(yáng)DF會(huì)每頁(yè)轉(zhuǎn)換為一張圖片,下面會(huì)有多頁(yè)組合成一頁(yè)的方法
     *
     * @param pdfFile pdf文件路徑
     * @param outPath 圖片輸出路徑
     * @param dpi 相當(dāng)于圖片的分辨率,值越大越清晰,但是轉(zhuǎn)換時(shí)間變長(zhǎng)
     */
    public static void pdf2multiImage(String pdfFile, String outPath, int dpi) {
        if (ObjectUtil.isEmpty(dpi)) {
            // 如果沒有設(shè)置DPI,默認(rèn)設(shè)置為150
            dpi = DEFAULT_DPI;
        }
        try (PDDocument pdf = PDDocument.load(new FileInputStream(pdfFile))) {
            int actSize = pdf.getNumberOfPages();
            List<BufferedImage> picList = Lists.newArrayList();
            for (int i = 0; i < actSize; i++) {
                BufferedImage image = new PDFRenderer(pdf).renderImageWithDPI(i, dpi, ImageType.RGB);
                picList.add(image);
            }
            // 組合圖片
            ImageUtil.yPic(picList, outPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

新建 ImageUtil 類

public class ImageUtil {

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ImageUtil.class);

    /**
     * 將寬度相同的圖片,豎向追加在一起 ##注意:寬度必須相同
     *
     * @param picList 文件流數(shù)組
     * @param outPath 輸出路徑
     */
    public static void yPic(List<BufferedImage> picList, String outPath) {// 縱向處理圖片
        if (picList == null || picList.size() <= 0) {
            log.info("圖片數(shù)組為空!");
            return;
        }
        try {
            // 總高度
            int height = 0,
                    // 總寬度
                    width = 0,
                    // 臨時(shí)的高度 , 或保存偏移高度
                    offsetHeight = 0,
                    // 臨時(shí)的高度,主要保存每個(gè)高度
                    tmpHeight = 0,
                    // 圖片的數(shù)量
                    picNum = picList.size();
            // 保存每個(gè)文件的高度
            int[] heightArray = new int[picNum];
            // 保存圖片流
            BufferedImage buffer = null;
            // 保存所有的圖片的RGB
            List<int[]> imgRgb = new ArrayList<int[]>();
            // 保存一張圖片中的RGB數(shù)據(jù)
            int[] tmpImgRgb;
            for (int i = 0; i < picNum; i++) {
                buffer = picList.get(i);
                // 圖片高度
                heightArray[i] = offsetHeight = buffer.getHeight();
                if (i == 0) {
                    // 圖片寬度
                    width = buffer.getWidth();
                }
                // 獲取總高度
                height += offsetHeight;
                // 從圖片中讀取RGB
                tmpImgRgb = new int[width * offsetHeight];
                tmpImgRgb = buffer.getRGB(0, 0, width, offsetHeight, tmpImgRgb, 0, width);
                imgRgb.add(tmpImgRgb);
            }
            // 設(shè)置偏移高度為0
            offsetHeight = 0;
            // 生成新圖片
            BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int i = 0; i < picNum; i++) {
                tmpHeight = heightArray[i];
                if (i != 0) {
                    // 計(jì)算偏移高度
                    offsetHeight += tmpHeight;
                }
                // 寫入流中
                imageResult.setRGB(0, offsetHeight, width, tmpHeight, imgRgb.get(i), 0, width);
            }
            File outFile = new File(outPath);
            // 寫圖片
            ImageIO.write(imageResult, "png", outFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容