生成PDF全攻略之在已有PDF上添加內(nèi)容的實(shí)現(xiàn)方法
項(xiàng)目在變,需求在變,不變的永遠(yuǎn)是敲擊鍵盤(pán)的程序員.....
PDF 生成后,有時(shí)候需要在PDF上面添加一些其他的內(nèi)容,比如文字,圖片....
經(jīng)歷幾次失敗的嘗試,終于獲取到了正確的代碼書(shū)寫(xiě)方式。
在此記錄總結(jié),方便下次以不變應(yīng)萬(wàn)變,需要的 jar 請(qǐng)移步:生成PDF全攻略
PdfReader reader = new PdfReader("E:\\A.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("E:\\B.pdf"));
PdfContentByte overContent = stamper.getOverContent(1);
上述的這段代碼算是在原有 PDF 上面添加內(nèi)容的核心代碼,具體流程如下

•如果看官老爺夠仔細(xì)的話(huà),該代碼是將原 A.pdf 讀取,然后將它寫(xiě)入 B.pdf,然后操作 B.pdf。
•可能有的看官老爺會(huì)說(shuō),將 A 讀取,然后在寫(xiě)入 A 中,這樣肯定是不行的,在讀取的時(shí)候 A 已經(jīng)被加載了,不能進(jìn)行修改。
•我不喜歡這種方式,因?yàn)樵?PDF 的信息已經(jīng)存儲(chǔ)在數(shù)據(jù)庫(kù)中,其中包括 PDF 的服務(wù)器路徑、舊名稱(chēng)、新名稱(chēng)、類(lèi)型......
•這樣就會(huì)多出一次數(shù)據(jù)庫(kù)變更操作,因?yàn)檫@里PDF名稱(chēng)需要變更,而且鬼知道后續(xù)需求還會(huì)怎么變。
•這里急需 只在 PDF 中添加內(nèi)容,其他的什么都不變,將代碼稍微調(diào)整了一下。
FileUtil.fileChannelCopy(A.pdf,A + "tmp".pdf)); PdfReader reader = new PdfReader(A + "tmp".pdf); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(A.pdf)); PdfContentByte overContent = stamper.getOverContent(1);
代碼流程就變做下面這個(gè)樣子

這里引入了管道復(fù)制文件,將A 復(fù)制一份,讀取副本,然后寫(xiě)回到原 PDF A 中,最后當(dāng)然需要?jiǎng)h除副本文件。
到這里,無(wú)論后續(xù)需求怎么變,保證了pdf 的其他屬性不變,就能從容面對(duì)。
管道復(fù)制代碼如下:
pubpc static void fileChannelCopy(File sources, File dest) {
try {
FileInputStream inputStream = new FileInputStream(sources);
FileOutputStream outputStream = new FileOutputStream(dest);
FileChannel fileChannepn = inputStream.getChannel();//得到對(duì)應(yīng)的文件通道
FileChannel fileChannelout = outputStream.getChannel();//得到對(duì)應(yīng)的文件通道
fileChannepn.transferTo(0, fileChannepn.size(), fileChannelout);//連接兩個(gè)通道,并且從in通道讀取,然后寫(xiě)入out通道
inputStream.close();
fileChannepn.close();
outputStream.close();
fileChannelout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
完整PDF其他內(nèi)容代碼如下:
FileUtil.fileChannelCopy(new File("E:\\A.pdf"),new File("E:\\A+"tmp".pdf"));
PdfReader reader = new PdfReader("E:\\A+"tmp".pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("E:\\A.pdf"));
PdfContentByte overContent = stamper.getOverContent(1);
//添加文字
BaseFont font = BaseFont.createFont("STSong-pght", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
overContent.beginText();
overContent.setFontAndSize(font, 10);
overContent.setTextMatrix(200, 200);
overContent.showTextApgned(Element.ApGN_CENTER,"需要添加的文字",580,530,0);
overContent.endText();
//添加圖片
PdfDictionary pdfDictionary = reader.getPageN(1);
PdfObject pdfObject = pdfDictionary.get(new PdfName("MediaBox"));
PdfArray pdfArray = (PdfArray) pdfObject;
Image image = Image.getInstance("D:\\1.jpg");
image.setAbsolutePosition(100,100);
overContent.addImage(image);
//添加一個(gè)紅圈
overContent.setRGBColorStroke(0xFF, 0x00, 0x00);
overContent.setpneWidth(5f);
overContent.elppse(250, 450, 350, 550);
overContent.stroke();
stamper.close();
以上這篇生成PDF全攻略之在已有PDF上添加內(nèi)容的實(shí)現(xiàn)方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot 如何實(shí)現(xiàn)Session共享
這篇文章主要介紹了SpringBoot 如何實(shí)現(xiàn)Session共享,幫助大家更好的理解和學(xué)習(xí)spring boot框架,感興趣的朋友可以了解下2020-09-09
詳解基于Spring Cloud幾行配置完成單點(diǎn)登錄開(kāi)發(fā)
這篇文章主要介紹了詳解基于Spring Cloud幾行配置完成單點(diǎn)登錄開(kāi)發(fā),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
SpringBoot集成Swagger2實(shí)現(xiàn)Restful(類(lèi)型轉(zhuǎn)換錯(cuò)誤解決辦法)
這篇文章主要介紹了SpringBoot集成Swagger2實(shí)現(xiàn)Restful(類(lèi)型轉(zhuǎn)換錯(cuò)誤解決辦法),需要的朋友可以參考下2017-07-07
Java實(shí)現(xiàn)TCP和UDP協(xié)議詳解
這篇文章主要介紹了Java實(shí)現(xiàn)TCP和UDP協(xié)議詳解,TCP(傳輸控制協(xié)議)和UDP(用戶(hù)數(shù)據(jù)報(bào)協(xié)議)是兩種最常用的傳輸層協(xié)議,它們都用于在網(wǎng)絡(luò)上傳輸數(shù)據(jù),但是它們之間有很多不同之處,需要的朋友可以參考下2023-07-07
java環(huán)境變量的配置方法圖文詳解【win10環(huán)境為例】
這篇文章主要介紹了java環(huán)境變量的配置方法,結(jié)合圖文形式詳細(xì)分析了win10環(huán)境下java環(huán)境變量的配置方法與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-04-04
spring常用注解開(kāi)發(fā)一個(gè)RESTful接口示例
這篇文章主要為大家介紹了使用spring常用注解開(kāi)發(fā)一個(gè)RESTful接口示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
微服務(wù)如何通過(guò)feign.RequestInterceptor傳遞參數(shù)
這篇文章主要介紹了微服務(wù)如何通過(guò)feign.RequestInterceptor傳遞參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Java中線(xiàn)程安全有哪些實(shí)現(xiàn)思路
在 Java 多線(xiàn)程編程中,線(xiàn)程安全是一個(gè)非常重要的概念,本文主要介紹了Java中線(xiàn)程安全有哪些實(shí)現(xiàn)思路,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2023-05-05

