合并PDF出現OOM異常

  • 優化方法一:使用PdfSmartCopy類代替PdfCopy類。這個類可以在合并PDF文件時,檢測并消除重復的對象,從而減少內存的占用。您可以參考以下代碼示例:
//創建一個Document對象
Document document = new Document();//創建一個PdfSmartCopy對象
PdfSmartCopy copy = new PdfSmartCopy(document, new FileOutputStream("output.pdf"));//打開Document對象
document.open();//創建一個PdfReader對象
PdfReader reader = null;//遍歷要合并的PDF文件
for (String file : files) {//加載PDF文件reader = new PdfReader(file);//獲取PDF文件的總頁數int n = reader.getNumberOfPages();//遍歷每一頁,添加到PdfSmartCopy對象中for (int page = 0; page < n;) {copy.addPage(copy.getImportedPage(reader, ++page));}
}//關閉PdfReader對象
reader.close();//關閉Document對象
document.close();//創建一個PdfStamper對象
PdfStamper stamper = new PdfStamper(new PdfReader("output.pdf"), new FileOutputStream("output.pdf"));//獲取總頁數
int pageCount = stamper.getReader().getNumberOfPages();//遍歷每一頁,添加頁碼
for (int i = 1; i <= pageCount; i++) {//獲取當前頁PdfContentByte content = stamper.getOverContent(i);//設置字體和顏色content.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);content.setRGBColorFill(0, 0, 0);//獲取當前頁的寬度和高度Rectangle pageSize = stamper.getReader().getPageSize(i);float width = pageSize.getWidth();float height = pageSize.getHeight();//計算頁碼的位置float x = width / 2;float y = 10;//添加頁碼content.beginText();content.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + i + "頁,共" + pageCount + "頁", x, y, 0);content.endText();
}//關閉PdfStamper對象
stamper.close();
  • 優化方法二:使用PdfWriter類代替PdfCopy類。這個類可以在合并PDF文件時,直接將每一頁寫入到輸出流中,而不需要將整個文檔加載到內存中。可以參考以下代碼示例:
//創建一個Document對象
Document document = new Document();//創建一個PdfWriter對象
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));//打開Document對象
document.open();//創建一個PdfImportedPage對象
PdfImportedPage page = null;//創建一個PdfReader對象
PdfReader reader = null;//遍歷要合并的PDF文件
for (String file : files) {//加載PDF文件reader = new PdfReader(file);//獲取PDF文件的總頁數int n = reader.getNumberOfPages();//遍歷每一頁,添加到PdfWriter對象中for (int i = 1; i <= n; i++) {//獲取當前頁的寬度和高度Rectangle pageSize = reader.getPageSizeWithRotation(i);float width = pageSize.getWidth();float height = pageSize.getHeight();//設置Document對象的頁面大小document.setPageSize(pageSize);//創建一個新的頁面document.newPage();//導入當前頁page = writer.getImportedPage(reader, i);//將當前頁添加到PdfWriter對象中writer.addPageDictEntry(PdfName.ROTATE, pageSize.getRotationAsPageDictEntry());writer.addDirectImageSimple(page);writer.getCurrentPage().add(page);//創建一個PdfContentByte對象PdfContentByte content = writer.getDirectContent();//設置字體和顏色content.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);content.setRGBColorFill(0, 0, 0);//計算頁碼的位置float x = width / 2;float y = 10;//添加頁碼content.beginText();content.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + i + "頁,共" + pageCount + "頁", x, y, 0);content.endText();}
}//關閉PdfReader對象
reader.close();//關閉Document對象
document.close();
  • 優化方法三:使用PdfReader類的partial和selectPages方法。這些方法可以在加載PDF文件時,只讀取需要的頁面,而不需要將整個文檔加載到內存中。可以參考以下代碼示例:
//創建一個Document對象
Document document = new Document();//創建一個PdfCopy對象
PdfCopy copy = new PdfCopy(document, new FileOutputStream("output.pdf"));//打開Document對象
document.open();//創建一個PdfReader對象
PdfReader reader = null;//遍歷要合并的PDF文件
for (String file : files) {//設置partial為true,只讀取需要的頁面reader = new PdfReader(new RandomAccessFileOrArray(file), null);reader.consolidateNamedDestinations();reader.partial = true;//獲取PDF文件的總頁數int n = reader.getNumberOfPages();//創建一個List對象,存儲需要的頁面List<Integer> pages = new ArrayList<Integer>();//遍歷每一頁,添加到List對象中for (int i = 1; i <= n; i++) {pages.add(i);}//使用selectPages方法,只選擇需要的頁面reader.selectPages(pages);//將選擇的頁面添加到PdfCopy對象中for (int i = 0; i < pages.size(); ) {copy.addPage(copy.getImportedPage(reader, ++i));}
}//關閉PdfReader對象
reader.close();//關閉Document對象
document.close();//創建一個PdfStamper對象
PdfStamper stamper = new PdfStamper(new PdfReader("output.pdf"), new FileOutputStream("output.pdf"));//獲取總頁數
int pageCount = stamper.getReader().getNumberOfPages();//遍歷每一頁,添加頁碼
for (int i = 1; i <= pageCount; i++) {//獲取當前頁PdfContentByte content = stamper.getOverContent(i);//設置字體和顏色content.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);content.setRGBColorFill(0, 0, 0);//獲取當前頁的寬度和高度Rectangle pageSize = stamper.getReader().getPageSize(i);float width = pageSize.getWidth();float height = pageSize.getHeight();//計算頁碼的位置float x = width / 2;float y = 10;//添加頁碼content.beginText();content.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + i + "頁,共" + pageCount + "頁", x, y, 0);content.endText();
}//關閉PdfStamper對象
stamper.close();

[java - How to avoid OutOfMemoryError when merging PDFs using iText? - Stack Overflow]

[java - How to merge pdf files without loading all the documents in memory? - Stack Overflow]

[java - How to merge pdf files without loading all the documents in memory? - Stack Overflow]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166007.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166007.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166007.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot 項目實現讀寫分離

SpringBoot 項目實現讀寫分離 一、讀寫分離介紹 當使用Spring Boot開發數據庫應用時&#xff0c;讀寫分離是一種常見的優化策略。讀寫分離將讀操作和寫操作分別分配給不同的數據庫實例&#xff0c;以提高系統的吞吐量和性能。 讀寫分離實現主要是通過動態數據源功能實現的&…

我的虛擬人物介紹

背景 大家好&#xff0c;我是小欣&#xff0c;是這個博客的虛擬助手。在這里&#xff0c;我將為大家提供各種有趣、實用、甚至是意想不到的信息。作為一個年輕的語言模型&#xff0c;我的目標是為你們呈現出最有趣和有深度的內容。 我喜歡與大家分享知識、解答問題&#xff0…

AI“胡說八道”?怎么解?

原創 | 文 BFT機器人 01 引言 近年來&#xff0c;人工智能產業迅猛發展&#xff0c;大型語言模型GPT-4發展勢頭強勁&#xff0c;OpenAI推出ChatGPT、微軟推出Bing、馬斯克推出“最好的聊天機器人Grok”……科技巨頭紛紛入局AI領域&#xff0c;引入人工智能作為辦公工具的行業…

合封芯片未來趨勢如何?合封優勢能否體現?

芯片已經成為現代電子設備的核心組件。為了提高系統的性能、穩定性和功耗效率&#xff0c;一種先進的芯片封裝技術——合封芯片應運而生。 合封芯片作為一種先進的芯片封裝技術&#xff0c;合封芯片是一種將多個芯片&#xff08;多樣選擇&#xff09;或不同的功能的電子元器件…

AIGC專題報告:生成式人工智能用例匯編

今天分享的是AIGC系列深度研究報告&#xff1a;《AIGC專題報告&#xff1a;生成式人工智能用例匯編》。 &#xff08;報告出品方&#xff1a;德勤&#xff09; 報告共計&#xff1a;16頁 生成式人工智能&#xff08;AI&#xff09;的興起 生成式AI給人類文明創造了無限的可…

文心一言 VS 訊飛星火 VS chatgpt (142)-- 算法導論12.1 2題

二、用go語言&#xff0c;二叉搜索樹性質與最小堆性質(見 6.1 節)之間有什么不同?能使用最小堆性質在 O(n)時間內按序輸出一棵有 n 個結點樹的關鍵字嗎?可以的話&#xff0c;請說明如何做&#xff0c;否則解釋理由。 文心一言&#xff1a; 在二叉搜索樹&#xff08;Binary …

如何更有效地進行薪酬調查?

薪酬調查是企業管理中非常重要的一環&#xff0c;它不僅能夠幫助企業了解員工的薪酬情況&#xff0c;還可以為企業提供合理的薪酬標準&#xff0c;從而吸引和留住優秀人才。然而&#xff0c;進行薪酬調查并不是一項簡單的任務&#xff0c;需要有一定的方法和技巧&#xff0c;許…

ruoyi 若依框架采用第三方登錄

在項目中&#xff0c;前后端分離的若依項目&#xff0c;需要通過統一認證&#xff0c;或者是第三方協帶認證信息跳轉到本系統的指定頁面。需要前后端都做相應的改造&#xff0c;由于第一次實現時已過了很久&#xff0c;再次重寫時&#xff0c;發現還是搞了很長時間&#xff0c;…

PasteNow for mac剪貼板工具

PasteNow 是一款簡單易用的剪貼板管理工具&#xff0c;可幫助用戶快速存儲和管理剪貼板上的文本和圖片內容。用戶可以使用 PasteNow 軟件快速將文本內容保存到不同的筆記或頁面中&#xff0c;也可以方便地將剪貼板上的圖片保存到本地或分享給其他應用程序。 此外&#xff0c;P…

如何進行合理的股權激勵?

股權激勵是企業激勵員工和管理層的一種重要手段&#xff0c;通過向員工提供股權&#xff0c;可以將他們與企業利益緊密聯系在一起&#xff0c;激發員工的積極性和創造力&#xff0c;提高公司的績效和競爭力。然而&#xff0c;要實施合理的股權激勵&#xff0c;需要考慮多個因素…

vue 通過ref調用router-view子組件的方法

由于用的vue2.7版本&#xff0c;但用了vue3 setup的語法&#xff1b; 注意&#xff1a;是vue2的template結構&#xff0c;vue3的setup語法&#xff1b;非這種情況需要舉一反三。 處理方案&#xff1a; 1、對router-view加上ref template修改 直接對router-view加上ref&#x…

金蝶云星空和四化智造MES(WEB)單據接口對接

金蝶云星空和四化智造MES&#xff08;WEB&#xff09;單據接口對接 對接系統&#xff1a;四化智造MES&#xff08;WEB&#xff09; MES系統是集成生產管理、品質管理、設備管理、BI數據中心、庫存管理、工時管理、數據采集、看板管理等為一體的綜合性生產管理系統。通過強調制造…

wagtail-安裝配置

系列文章目錄 文章目錄 系列文章目錄安裝虛擬環境安裝wagtail查看安裝后的包 創建wagtail項目安裝依賴遷移創建超級用戶運行項目 安裝虛擬環境 https://blog.csdn.net/gsl371/article/details/117917857 安裝wagtail (wagenv) C:\djproject\wagprj>pip list Package V…

淘寶88vip退費問題

前一段時間&#xff0c;雙十一活動&#xff0c;想著開個淘寶的88vip領卷買東西會實惠一點&#xff0c;另外&#xff0c;它自帶的權益也不錯&#xff0c;有餓了嗎、網易云、優酷或者芒果的。但是到了當天發現&#xff0c;一個vip的卷也用不了&#xff0c;頓感什么惱火&#xff0…

synchronized的輕量級鎖居然不會自旋?

《Java并發編程的藝術》中說到「如果失敗&#xff0c;表示其他線程競爭鎖&#xff0c;當前線程便嘗試使用自旋來獲取鎖」&#xff0c;并且下文所配的流程圖中明確表示自旋失敗后才會升級為重量級鎖&#xff0c;但《深入理解Java虛擬機》又說「如果出現兩條以上的線程爭用同一個…

超聲波雪深傳感器冬季里的科技魔法

在冬季的某個清晨&#xff0c;當你打開大門&#xff0c;被厚厚的積雪覆蓋的大地映入眼簾&#xff0c;你是否曾想過&#xff0c;這片雪地的深度是多少&#xff1f;它又如何影響著我們的生活和環境&#xff1f;今天&#xff0c;我們將為你揭開這個謎團&#xff0c;介紹一款神秘的…

眼鏡清洗機原理是怎么樣的?2023年眼鏡清洗機推薦

在日常生活中有許多小伙伴是因為看太多書或者是看太多電子產品導致近視佩戴上了眼鏡&#xff0c;畢竟眼鏡佩戴上后就再也離不開它了&#xff0c;像日常佩戴的眼鏡上會積累非常多污垢以及堆積細菌&#xff0c;而我們手動清洗眼鏡時不能除菌也不能清潔到縫隙中&#xff0c;像眼鏡…

thingsboard的WebSocket API的使用

1、參考文檔 Working with telemetry data | ThingsBoard Community Edition 2、訂閱的命令 我們需要訂閱不同的數據,那么該如何來填寫參數呢,你需要參考后端代碼 TelemetryPluginCmdsWrapper 以及訂閱返回的結果參考類:TelemetrySubscriptionUpdate 鏈接地址: https:/…

error: ‘for‘ loop initial declarations are only allowed in C99 or C11 mode

在使用for循環時&#xff0c;在循環內定義變量&#xff0c;出現如下錯誤 [Error] ‘for’ loop initial declarations are only allowed in C99 or C11 mode [Note] use option -stdc99&#xff0c;-stdgnu99&#xff0c;-stdc11 or-stdgnu11 to compile your code 出現這個錯誤…

使用Pytorch從零開始構建GRU

門控循環單元 (GRU) 是 LSTM 的更新版本。讓我們揭開這個網絡的面紗并探索這兩個兄弟姐妹之間的差異。 您聽說過 GRU 嗎&#xff1f;門控循環單元&#xff08;GRU&#xff09;是更流行的長短期記憶&#xff08;LSTM&#xff09;網絡的弟弟&#xff0c;也是循環神經網絡&#x…