2017-03-03 78 views
3

我使用Apache的PDFBox庫編寫PdfDocumentBuilder類。我在使用currentFont.hasGlyph(character)來檢查一個字符是否有字形,然後再嘗試寫入文件。問題是,當字符是像'\u001f'這樣的Unicode字符控制字符時,hasGlyph()返回true,寫入時會引發encode()異常(請參閱下面的PdfDocumentBuilder代碼和堆棧跟蹤以供參考)。PDFBox hasGlyph()對不受支持的unicode控制字符返回true

我做了一些研究,看來這些unicode控制字符不支持我使用的字體(Courier Prime)。

那麼爲什麼hasGlyph()在unicode控制字符不支持時返回true?當然,在我輸入writeTextWithSymbol()方法之前,我可以用簡單的replaceAll去除線上的控制字符,但是如果hasGlyph()方法不能像我期望的那樣工作,那麼我遇到了更大的問題。

PdfDocumentBuilder:

private final PDType0Font baseFont; 
private PDType0Font currentFont; 

public PdfDocumentBuilder() { 
    baseFont = PDType0Font.load(doc, this.getClass().getResourceAsStream("/CourierPrime.ttf")); 
    currentFont = baseFont; 
} 

private void writeTextWithSymbol (String text) throws IOException { 
    StringBuilder nonSymbolBuffer = new StringBuilder(); 
    for (char character : text.toCharArray()) { 
     if (currentFont.hasGlyph(character)) { 
      nonSymbolBuffer.append(character); 
     } else { 
      //handling writing line with symbols... 
     } 
    } 
    if (nonSymbolBuffer.length() > 0) { 
     content.showText(nonSymbolBuffer.toString()); 
    } 
} 

堆棧跟蹤:

java.lang.IllegalArgumentException: No glyph for U+001F in font CourierPrime 
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.encode(PDCIDFontType2.java:400) 
at org.apache.pdfbox.pdmodel.font.PDType0Font.encode(PDType0Font.java:351) 
at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:316) 
at org.apache.pdfbox.pdmodel.PDPageContentStream.showText(PDPageContentStream.java:414) 
at org.main.export.PdfDocumentBuilder.writeTextWithSymbol(PdfDocumentBuilder.java:193) 
+1

你使用的是什麼版本?最新的版本是2.0.4,所以請重試一次。這種效果是否也會像Arial這樣的普通字體發生?你是如何創建字體對象的? –

+0

@TilmanHausherr我正在使用2.0.4。我已經測試了一些其他標準字體,問題仍然存在。我添加了創建currentFont對象的代碼。 –

+0

我創建了一個簡單的測試,是的,它也發生在Arial上。我認爲bug是在hasGlyph中,或者hasGlyph中的參數不是人們會想到的。對你而言,最好的方法是用每個字符調用font.encode()並捕獲IllegalArgumentException,以知道該字符是否受支持。這種方式你肯定知道。我會在以後的JIRA中創建一個問題。 –

回答

3

如上評論解釋,hasGlyph()並不意味着接受Unicode字符作爲參數。所以如果你需要檢查一個字符在寫入之前是否可以編碼,你可以這樣做:

private void writeTextWithSymbol (String text) throws IOException { 
    StringBuilder nonSymbolBuffer = new StringBuilder(); 
    for (char character : text.toCharArray()) { 
     if (isCharacterEncodeable(character)) { 
      nonSymbolBuffer.append(character); 
     } else { 
      //handle writing line with symbols... 
     } 
    } 
    if (nonSymbolBuffer.length() > 0) { 
     content.showText(nonSymbolBuffer.toString()); 
    } 
} 

private boolean isCharacterEncodeable (char character) throws IOException { 
    try { 
     currentFont.encode(Character.toString(character)); 
     return true; 
    } catch (IllegalArgumentException iae) { 
     LOGGER.trace("Character cannot be encoded", iae); 
     return false; 
    } 
} 
+0

您在'isCharacterEncodeable()'中捕獲'IOException'。你不應該抓住'IllegalArgumentException'嗎? –

+0

@TilmanHausherr好抓 –

相關問題