2013-10-11 229 views
2

我想將標題添加到現有的PDF文件。它可以工作,但現有PDF中的表格標題會因字體更改而混亂。如果我刪除設置字體,那麼標題不顯示。這裏是我的代碼:使用PDFBox將標題添加到現有的PDF文件

// the document 
    PDDocument doc = null; 
    try 
    { 
     doc = PDDocument.load(file); 

     List allPages = doc.getDocumentCatalog().getAllPages(); 
     //PDFont font = PDType1Font.HELVETICA_BOLD; 

     for(int i=0; i<allPages.size(); i++) 
     { 
      PDPage page = (PDPage)allPages.get(i); 
      PDRectangle pageSize = page.findMediaBox(); 
      PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true,true); 
      PDFont font = PDType1Font.TIMES_ROMAN; 
      float fontSize = 15.0f; 
      contentStream.beginText(); 
      // set font and font size 
      contentStream.setFont(font, fontSize); 
      contentStream.moveTextPositionByAmount(700, 1150); 
      contentStream.drawString(message); 
      contentStream.endText(); 

      //contentStream. 
      contentStream.close();} 

     doc.save(outfile); 
    } 
    finally 
    { 
     if(doc != null) 
     { 
      doc.close(); 
     } 
    } 
}` 
+0

*現有PDF中的表頭被搞亂* - 它們到底有多混亂? – mkl

+0

使用的字體使表頭不可讀。對於例如表格標題曾經是PMITS Asset ID,並且在添加標題後讀取爲:3 0,7 6 $ V V H W.一些gibrish字符。 –

+0

所以你的源PDF或PDFBox是越野車。不幸的是,我已經認識到PDFBox代碼中可能導致您的問題的一個問題:頁面不一定有自己的資源池,但可以從頁面樹中的祖先繼承它。另一方面,PDPageContentStream忽略這樣的繼承資源,並在這種情況下爲頁面創建一個新的空白資源池。因此,在這種情況下遺失的字體信息會丟失。這可能會導致你的gibrish。請提供有問題的PDF以驗證這個PDFBox錯誤是否確實是您觀察到的問題。 – mkl

回答

6

本質上,您正在運行到當前版本1.8.2的PDFBox錯誤。

一種解決方法:

添加getFonts調用的頁面資源的使用字體之前創建新的內容流後:

PDPage page = (PDPage)allPages.get(i); 
PDRectangle pageSize = page.findMediaBox(); 
PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true,true); 
page.getResources().getFonts(); // <<<<<<<< 
PDFont font = PDType1Font.TIMES_ROMAN; 
float fontSize = 15.0f; 
contentStream.beginText(); 

修正它:

bug是在方法PDResources.addFontPDPageContentStream.setFont調用:

public String addFont(PDFont font) 
{ 
    return addFont(font, MapUtil.getNextUniqueKey(fonts, "F")); 
} 

它使用fonts成員變量的當前內容來確定手頭頁面上新字體資源的唯一名稱。不幸的是,這個成員變量仍然可能是(在你的情況下)此時未初始化。這導致MapUtil.getNextUniqueKey(fonts, "F")呼叫始終返回F0

font變量隨後在addFont(PDFont, String)調用中被隱式初始化。

因此,如果不幸在該頁面上已經存在一個名爲F0的字體,它將被替換爲新的字體。

經過您的PDF測試,這正是您的情況。由於現有字體F0使用一些自定義編碼,而替換字體使用標準字體,所以最初使用F0編寫的文本現在看起來很亂。

上述解決方法隱式初始化該成員變量,從而防止字體替換。

如果您計劃在生產中使用PDFBox進行此任務,您可能需要報告該錯誤。 PS:正如上面的評論中提到的那樣,在繼承資源的上下文中還有另一個bug。它也應該引起PDFBox開發者的注意。

PPS:與此同時,PDFBox中的版本1.8.3和2.0.0已經解決了問題,參見參考資料。 PDFBOX-1753

+0

非常感謝你mkl,這就像一個冠軍。再次感謝您花時間研究這個問題。 –

相關問題