亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java使用PDFBox實現(xiàn)操作PDF文檔

 更新時間:2024年03月22日 16:55:40   作者:芝麻粒兒  
這篇文章主要為大家詳細介紹了Java如何使用PDFBox實現(xiàn)操作PDF文檔,例如添加本地圖片、添加網(wǎng)絡(luò)圖片、圖片寬高自適應(yīng)、圖片水平垂直居中對齊等功能,需要的可以了解下

PDFBox操作圖片

PDFBox可以向PDF文檔中添加圖片對象,使用PDImageXObject表示一個圖片對象,對PDF文檔的內(nèi)容進行操作,都需要借助于PDPageContentStream頁面內(nèi)容流對象來完成,PDFBox將每一個PDF頁面中的所有文本、圖片、表單等內(nèi)容看作一個流,通過流的方式來完成內(nèi)容的添加、刪除、修改等操作。這里首先介紹如何使用PDFBox添加圖片對象到PDF文檔里面。

添加本地圖片

(1)案例代碼

添加本地圖片,也就是讀取當前磁盤中的圖片,然后將這個圖片寫入到PDPageContentStream頁面內(nèi)容流里面,案例代碼如下:

package pdfbox.demo.image;
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 
/**
 * @version 1.0.0
 * @Date: 2023/7/15 14:51
 * @Author ZhuYouBin
 * @Description: PDFBox操作圖片
 */
public class PDFBoxImageUtil {
 
    /**
     * 將給定路徑的圖片,保存到pdf文件里面
     * @param imgPath 圖片路徑
     * @param destPdf 生成的pdf文件路徑
     * @return 返回生成的pdf文件路徑
     */
    public static String generateImageToPdf(String imgPath, String destPdf) {
        try {
            // 1、創(chuàng)建PDF文檔對象
            PDDocument doc = new PDDocument();
            // 2、創(chuàng)建Page頁面對象
            PDPage page = new PDPage(PDRectangle.A4);
            // 3、創(chuàng)建圖片對象
            PDImageXObject image = PDImageXObject.createFromFile(imgPath, doc);
            // 4、創(chuàng)建頁面內(nèi)容流,指定操作哪個文檔中的哪個頁面
            PDPageContentStream stream = new PDPageContentStream(doc, page);
            stream.drawImage(image, 10, 10); // 繪制圖片到PDF頁面里面
            stream.close(); // 關(guān)閉頁面內(nèi)容流
            doc.addPage(page); // 添加頁面到PDF文檔
            doc.save(destPdf); // 保存PDF文檔
            doc.close(); // 關(guān)閉PDF文檔
        } catch (Exception e) {
            e.printStackTrace();
        }
        return destPdf;
    }
 
    public static void main(String[] args) {
        String imgPath = "E:\\demo\\001.jpg";
        String destPdf = "E:\\demo\\img.pdf";
        generateImageToPdf(imgPath, destPdf);
    }
}

(2)運行效果

(3)方法介紹

PDImageXObject類中提個了一些靜態(tài)方法,常見的有下面這些:

createFromFile(imagePath,doc)方法:采用File文件的方式讀取本地磁盤中的圖片。

  • imagePath參數(shù):圖片的路徑。
  • doc參數(shù):PDF文檔對象。

getImage()方法:返回BufferedImage圖片對象。

getSuffix()方法:返回圖片的后綴類型,例如:jpg、png等。

添加網(wǎng)絡(luò)圖片

PDFBox中是沒有提供讀取網(wǎng)絡(luò)圖片的方法,但是可以采用下面這種方式實現(xiàn)讀取網(wǎng)絡(luò)圖片的功能,思路如下:

  • 第一步:使用URL對象將網(wǎng)絡(luò)圖片下載到本地磁盤上。
  • 第二步:使用createFromFile()方法從本地磁盤讀取剛剛下載的網(wǎng)絡(luò)圖片。

(1)案例代碼

package pdfbox.demo.image;
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;
 
/**
 * @version 1.0.0
 * @Date: 2023/7/15 15:01
 * @Author ZhuYouBin
 * @Description: PDFBox操作圖片,添加網(wǎng)絡(luò)圖片到PDF文檔
 */
public class PDFBoxImageUtil {
 
    /**
     * 將給定路徑的圖片,保存到pdf文件里面
     * @param imgPath 圖片路徑
     * @param destPdf 生成的pdf文件路徑
     * @return 是否生成成功
     */
    public static String generateImageToPdf(String imgPath, String destPdf) {
        try {
            // 1、創(chuàng)建PDF文檔對象
            PDDocument doc = new PDDocument();
            // 2、創(chuàng)建Page頁面對象
            PDPage page = new PDPage(PDRectangle.A4);
            // 3、創(chuàng)建圖片對象
            PDImageXObject image;
            boolean isTemp = false;
            String tempPath = null;
            if (imgPath.startsWith("http://") || imgPath.startsWith("https://")) {
                isTemp = true;
                tempPath = downloadImage(imgPath, null);
                image = PDImageXObject.createFromFile(tempPath, doc);
            } else {
                image = PDImageXObject.createFromFile(imgPath, doc);
            }
            // 4、創(chuàng)建頁面內(nèi)容流,指定操作哪個文檔中的哪個頁面
            PDPageContentStream stream = new PDPageContentStream(doc, page);
            stream.drawImage(image, 10, 10); // 繪制圖片到PDF頁面里面
            stream.close(); // 關(guān)閉頁面內(nèi)容流
            doc.addPage(page); // 添加頁面到PDF文檔
            doc.save(destPdf); // 保存PDF文檔
            doc.close(); // 關(guān)閉PDF文檔
            // 圖片添加成功之后需要刪除本地臨時文件
            if (isTemp) {
                new File(tempPath).delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return destPdf;
    }
 
    /**
     * 下載網(wǎng)絡(luò)圖片到本地
     * @param imgPath 網(wǎng)絡(luò)圖片地址
     * @param fileName 文件名稱
     * @return 返回本地圖片的臨時路徑
     */
    public static String downloadImage(String imgPath, String fileName) {
        try {
            URLConnection conn = new URL(imgPath).openConnection();
            String contentType = conn.getContentType();
            System.out.println(contentType);
            // 創(chuàng)建臨時文件目錄保存圖片
            File file = new File("temp");
            if (!file.exists() && !file.mkdirs()) {
                throw new RuntimeException("臨時目錄創(chuàng)建失敗");
            }
            if (fileName == null || fileName.trim().equals("")) {
                fileName = UUID.randomUUID().toString();
            }
            InputStream is = conn.getInputStream();
            byte[] data = new byte[1024];
            int len;
            // 下載文件到本地臨時目錄
            switch (contentType) {
                case "image/jpeg":fileName += ".jpeg"; break;
                case "image/gif": fileName += ".gif"; break;
                case "image/webp":
                case "image/png": fileName += ".png"; break;
            }
            fileName = file.getAbsolutePath() + File.separator + fileName;
            FileOutputStream fos = new FileOutputStream(fileName);
            while ((len = is.read(data)) != -1) {
                fos.write(data, 0, len);
            }
            fos.close();
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }
 
    public static void main(String[] args) {
        String imgPath = "https://www.toopic.cn/public/uploads/small/1658043938262165804393852.jpg";
        String destPdf = "E:\\demo\\img.pdf";
        generateImageToPdf(imgPath, destPdf);
    }
}

(2)運行效果

圖片寬高自適應(yīng)(圖片縮放)

前面已經(jīng)能夠?qū)D片添加到PDF文檔中了,但是可以發(fā)現(xiàn),我們添加的圖片尺寸太大的時候,超過PDF文檔部分就會被遮擋,如何解決這個問題呢???對于這個問題,可以采用縮放圖片的方式來解決,思路如下所示:

  • 第一步:獲取圖片的實際寬度、高度(JDK中獲取到的圖片寬高單位是【px】,需要將【px】轉(zhuǎn)換成【pt】單位,轉(zhuǎn)換規(guī)則:1pt = 3/4 px)。
  • 第二步:獲取到PDF文檔的寬度、高度(PDFBox中獲取到的寬度、高度是采用【pt】作為單位的)。
  • 第三步:圖片的實際寬高和PDF文檔的寬高進行比較,計算縮放比例。

圖片縮放代碼

package pdfbox.demo.image;
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;
 
/**
 * @version 1.0.0
 * @Date: 2023/7/15 15:11
 * @Author ZhuYouBin
 * @Description: PDFBox操作圖片,圖片寬高自動縮放
 */
public class PDFBoxImageUtil {
 
    /**
     * 將給定路徑的圖片,保存到pdf文件里面
     *
     * @param imgPath 圖片路徑
     * @param destPdf 生成的pdf文件路徑
     * @return 返回生成的pdf文件路徑
     */
    public static boolean generateImageToPdf(String imgPath, String destPdf) {
        try {
            // 1、創(chuàng)建PDF文檔對象
            PDDocument doc = new PDDocument();
            // 2、創(chuàng)建Page頁面對象
            PDPage page = new PDPage(PDRectangle.A4);
            // 3、創(chuàng)建圖片對象
            PDImageXObject image;
            if (imgPath.startsWith("http://") || imgPath.startsWith("https://")) {
                String tempPath = downloadImage(imgPath, null);
                image = PDImageXObject.createFromFile(tempPath, doc);
                imgPath = tempPath;
            } else {
                image = PDImageXObject.createFromFile(imgPath, doc);
            }
            // 4、創(chuàng)建頁面內(nèi)容流,指定操作哪個文檔中的哪個頁面
            PDPageContentStream stream = new PDPageContentStream(doc, page);
            // 獲取圖片的寬高
            float[] imageWH = getImageWH(imgPath, page.getMediaBox());
            stream.drawImage(image, imageWH[0], imageWH[1], imageWH[2], imageWH[3]); // 繪制圖片到PDF頁面里面
            stream.close(); // 關(guān)閉頁面內(nèi)容流
            doc.addPage(page); // 添加頁面到PDF文檔
            doc.save(destPdf); // 保存PDF文檔
            doc.close(); // 關(guān)閉PDF文檔
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
 
    /**
     * 獲取圖片的寬度、高度,單位是【pt】
     *
     * @param imgPath 圖片路徑
     * @param box     PDF文檔頁面矩形區(qū)域?qū)ο?,可以獲取到矩形區(qū)域的寬高
     * @return 返回縮放之后的圖片寬高
     */
    public static float[] getImageWH(String imgPath, PDRectangle box) {
        try {
            File file = new File(imgPath);
            InputStream is = new FileInputStream(file);
            // 判斷是不是網(wǎng)絡(luò)上的圖片
            if (imgPath.startsWith("http://") || imgPath.startsWith("https://")) {
                is = new URL(imgPath).openStream();
            }
            BufferedImage bi = ImageIO.read(is);
            // px 轉(zhuǎn)換成 pt 單位
            float xAxis;
            float yAxis;
            int w = bi.getWidth();
            int h = bi.getHeight();
            float width = (float) (w * 3.0 / 4); // 這里是因為 1pt = 3/4 px,pt和px單位轉(zhuǎn)換
            float height = (float) (h * 3.0 / 4);
            float pw = box.getWidth() - 60; // 這里減不減60沒啥關(guān)系,只是設(shè)置一下空白間距
            float ph = box.getHeight() - 60; // 這里減不減60沒啥關(guān)系,只是設(shè)置一下空白間距
            if (width > pw) {
                float scale = pw / width;  // 縮放比列
                width = pw; // 寬度等于頁面寬度
                height = height * scale; // 高度自動縮放
            } else {
                float scale = ph / height;  // 縮放比列
                height = ph; // 高度等于頁面高度
                width = width * scale;  // 寬度自動縮放
            }
            // 計算圖片在X、Y軸上的顯示位置
            xAxis = (box.getWidth() - width) / 2; // X軸居中對齊
//            yAxis = box.getHeight() - height - 10; // 距離頁面頂部10個pt
            yAxis = (box.getHeight() - height) / 2; // Y軸垂直居中對齊
            return new float[]{xAxis, yAxis, width, height};
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new float[]{0, 0, 0, 0};
    }
 
    /**
     * 下載網(wǎng)絡(luò)圖片到本地
     * @param imgPath 網(wǎng)絡(luò)圖片地址
     * @param fileName 文件名稱
     * @return 返回本地圖片的臨時路徑
     */
    public static String downloadImage(String imgPath, String fileName) {
        try {
            URLConnection conn = new URL(imgPath).openConnection();
            String contentType = conn.getContentType();
            // 創(chuàng)建臨時文件目錄保存圖片
            File file = new File("temp");
            if (!file.exists() && !file.mkdirs()) {
                throw new RuntimeException("臨時目錄創(chuàng)建失敗");
            }
            if (fileName == null || fileName.trim().equals("")) {
                fileName = UUID.randomUUID().toString().replaceAll("-", "");
            }
            InputStream is = conn.getInputStream();
            byte[] data = new byte[1024];
            int len;
            // 下載文件到本地臨時目錄
            switch (contentType) {
                case "image/jpeg":fileName += ".jpeg"; break;
                case "image/gif": fileName += ".gif"; break;
                case "image/webp":
                case "image/png": fileName += ".png"; break;
            }
            fileName = file.getAbsolutePath() + File.separator + fileName;
            FileOutputStream fos = new FileOutputStream(fileName);
            while ((len = is.read(data)) != -1) {
                fos.write(data, 0, len);
            }
            fos.close();
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }
 
    public static void main(String[] args) {
        String imgPath = "https://www.toopic.cn/public/uploads/small/1658043938262165804393852.jpg";
        String destPdf = "E:\\demo\\img.pdf";
        generateImageToPdf(imgPath, destPdf);
    }
}

讀取圖片

PDFBox也可以從PDF文檔中讀取圖片,然后將其保存到本地磁盤中,保存圖片可以使用JDK中提供的ImageIO類,這個類中提供了一個write()方法,可以將圖片對象寫入到File文件里面。

(1)案例代碼

package pdfbox.demo.image;
 
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
 
/**
 * @version 1.0.0
 * @Date: 2023/7/15 15:11
 * @Author ZhuYouBin
 * @Description: PDFBox操作圖片,從PDF文檔中【讀取圖片】,并且保存到本地
 */
public class PDFBoxImageUtil {
 
    /**
     * 從給定的pdf文檔里面,獲取指定頁面中的所有圖片,并且保存到本地目錄下
     * <p>
     *     pdf文檔中的圖片都是BASE64編碼,我們能夠獲取到的也就只能是圖片對應(yīng)的BASE64字符串。
     *     所以,還需要將圖片的BASE64字符串編碼轉(zhuǎn)換成對應(yīng)的圖片文件
     * </p>
     * @param pdfPath PDF文檔路徑
     * @param imagePath 生成的圖片路徑以及名稱
     * @param pageNum 獲取第幾頁的圖片
     * @return 返回提取的圖片本地路徑
     */
    public static String readerImageFromPdf(String pdfPath, String imagePath, int pageNum) {
        try {
            // 1、加載PDF文檔
            PDDocument doc = PDDocument.load(new File(pdfPath));
            // 2、遍歷所有Page頁面,找到指定的page頁面獲取圖片
            int pages = doc.getNumberOfPages();
            for (int i = 0; i < pages; i++) {
                if (i != pageNum) {
                    continue;
                }
                // 獲取當前Page頁面
                PDPage page = doc.getPage(i);
                // 獲取對應(yīng)頁面的資源對象
                PDResources resources = page.getResources();
                // 遍歷當前頁面所有內(nèi)容,找出圖片對象
                for (COSName cosName : resources.getXObjectNames()) {
                    PDXObject pdxObject = resources.getXObject(cosName);
                    // 判斷是不是圖片對象
                    if (pdxObject instanceof PDImageXObject) {
                        // 獲取圖片對象
                        BufferedImage image = ((PDImageXObject) pdxObject).getImage();
                        // 保存到本地磁盤里面
                        ImageIO.write(image, "JPEG", new File(imagePath));
                    }
                }
            }
            doc.close(); // 關(guān)閉PDF文檔
        } catch (Exception e) {
            e.printStackTrace();
        }
        return imagePath;
    }
 
    public static void main(String[] args) {
        String imgPath = "E:\\img\\002.jpg";
        String destPdf = "E:\\demo\\img.pdf";
        readerImageFromPdf(destPdf, imgPath, 0);
    }
}

(2)運行效果

到此,PDFBox操作圖片就介紹完啦。

以上就是Java使用PDFBox實現(xiàn)操作PDF文檔的詳細內(nèi)容,更多關(guān)于Java PDFBox操作PDF的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JAVA JVM運行時數(shù)據(jù)區(qū)詳解

    JAVA JVM運行時數(shù)據(jù)區(qū)詳解

    這篇文章主要介紹了JVM運行時數(shù)據(jù)區(qū)劃分原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2021-09-09
  • 30分鐘入門Java8之默認方法和靜態(tài)接口方法學(xué)習(xí)

    30分鐘入門Java8之默認方法和靜態(tài)接口方法學(xué)習(xí)

    這篇文章主要介紹了30分鐘入門Java8之默認方法和靜態(tài)接口方法學(xué)習(xí),詳細介紹了默認方法和接口,有興趣的可以了解一下。
    2017-04-04
  • idea2020.1.3 手把手教你創(chuàng)建web項目的方法步驟

    idea2020.1.3 手把手教你創(chuàng)建web項目的方法步驟

    這篇文章主要介紹了idea 2020.1.3 手把手教你創(chuàng)建web項目的方法步驟,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java實現(xiàn)本地緩存的方式匯總

    Java實現(xiàn)本地緩存的方式匯總

    引入緩存,主要用于實現(xiàn)系統(tǒng)的高性能,高并發(fā),這篇文章主要介紹了Java實現(xiàn)本地緩存的幾種方式,本文結(jié)合示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Java內(nèi)存各部分OOM出現(xiàn)原因及解決方法(必看)

    Java內(nèi)存各部分OOM出現(xiàn)原因及解決方法(必看)

    下面小編就為大家?guī)硪黄狫ava內(nèi)存各部分OOM出現(xiàn)原因及解決方法(必看)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • Spring實戰(zhàn)之Bean的作用域request用法分析

    Spring實戰(zhàn)之Bean的作用域request用法分析

    這篇文章主要介紹了Spring實戰(zhàn)之Bean的作用域request用法,結(jié)合實例形式分析了spring中Bean的request作用域相關(guān)使用技巧與操作注意事項,需要的朋友可以參考下
    2019-11-11
  • Java8 Instant 時間戳實例講解

    Java8 Instant 時間戳實例講解

    Instant類是Java8 中補充的一個 時間戳類,nstant 可以使用靜態(tài)方法 now()或者of()方法來創(chuàng)建一個實例對象,本文通過實例代碼講解Java8 Instant 時間戳,感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • java實現(xiàn)高效下載文件的方法

    java實現(xiàn)高效下載文件的方法

    這篇文章主要為大家詳細介紹了java實現(xiàn)高效下載文件的幾種方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 詳解Java中StringBuffer類常用方法

    詳解Java中StringBuffer類常用方法

    這篇文章主要為大家介紹了java中StringBuffer類常用方法
    2016-01-01
  • JAVA實現(xiàn)遍歷文件夾下的所有文件(遞歸調(diào)用和非遞歸調(diào)用)

    JAVA實現(xiàn)遍歷文件夾下的所有文件(遞歸調(diào)用和非遞歸調(diào)用)

    本篇文章主要介紹了JAVA 遍歷文件夾下的所有文件(遞歸調(diào)用和非遞歸調(diào)用) ,具有一定的參考價值,有興趣的可以了解一下。
    2017-01-01

最新評論