나는 PDFBox를 내 유니 코드로 인쇄하는 데 성공했습니다. 하지만 이제는 제가 생각해 낸 해결책을 이해하고 싶습니다. 아래 코드는 작동하여 페이지에 ≥
을 인쇄합니다.PDFBox 2.0에서 글꼴로드 이해
두 가지가 작동하지 않습니다 :
변화
PDType0Font.load(documentMock, systemResourceAsStream, true);
final PDFont robotoLight = loadFontAlternative("Roboto-Light.ttf");
final PDFont robotoLight = loadFont("Roboto-Light.ttf");
PDType0Font.load(documentMock, systemResourceAsStream, false);
에
첫 번째 변경은 문자 대신 두 개의 점을 인쇄합니다. false로 설정하면 작동하지 않으므로 embedSubset은 무엇을합니까? 문서가 너무 작아 이해할 수 없습니다.
두 번째 변경 내용은 다음 예외를 나타냅니다. Exception in thread "main" java.lang.IllegalArgumentException: U+2265 is not available in this font's encoding: WinAnsiEncoding
이 문제는 unicode 처리시 버그가있는 PDFBox 2.0 이전의 많은 다른 질문에서 다루어졌습니다. 그래서 그들은 직접 질문에 대답하지 않습니다. 그건 그렇고, 문제는 분명합니다 : 나는 인코딩을 WinAnsiEncoding하지만 다른 설정으로해서는 안된다. 하지만 인코딩은 어떻게해야합니까? 및 UTF-8 인코딩이 없거나 유사한 이유가 무엇입니까? COSName에 많은 옵션에 대한 문서가 없습니다.
public class SimpleReportUnicode {
public static void main(String[] args) throws IOException {
PDDocument report = createReport();
final String fileLocation = "c:/SimpleFormUnicode.pdf";
report.save(fileLocation);
report.close();
}
private static PDDocument createReport() throws IOException {
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
final PDFont robotoLight = loadFontAlternative("Roboto-Light.ttf");
writeText(contentStream, robotoLight, 100, 650);
contentStream.close();
return document;
}
private static void writeText(PDPageContentStream contentStream, PDFont font, double x, double y) {
try {
contentStream.beginText();
contentStream.setFont(font, 12);
contentStream.moveTextPositionByAmount((float) x, (float) y);
String unicode = "≥";
contentStream.showText(unicode);
contentStream.endText();
}
catch (IOException e) {
}
}
private static PDFont loadFont(String location) {
PDFont font;
try {
PDDocument documentMock = new PDDocument();
InputStream systemResourceAsStream = ClassLoader.getSystemResourceAsStream(location);
Encoding encoding = Encoding.getInstance(COSName.WIN_ANSI_ENCODING);
font = PDTrueTypeFont.load(documentMock, systemResourceAsStream, encoding);
}
catch (IOException e) {
throw new RuntimeException("IO exception");
}
return font;
}
private static PDFont loadFontAlternative(String location) {
PDDocument documentMock = new PDDocument();
InputStream systemResourceAsStream = ClassLoader.getSystemResourceAsStream(location);
PDFont font;
try {
font = PDType0Font.load(documentMock, systemResourceAsStream, true);
}
catch (IOException e) {
throw new RuntimeException("IO exception");
}
return font;
}
}
편집 당신이 코드에서와 동일한 글꼴을 사용하려면, Roboto로 여기에 있습니다 : https://fonts.google.com/specimen/Roboto 당신이 클래스 경로 코드가 상자 밖으로 작동합니다에 Roboto로-Light.ttf 추가 . 주석에서 설명하고있는 바와 같이
어떤 PDFBox 버전을 사용하고 있습니까? –
"U + 2265는이 글꼴의 인코딩에서 사용할 수 없습니다 : WinAnsiEncoding"은 FAQ : https://pdfbox.apache.org/2.0/faq.html#fontencoding에서 설명합니다. 'PDType0Font.load()'는 마지막 매개 변수가 참인지 거짓인지에 관계없이 나를 위해 작동합니다. True는 부분 집합을 의미하고, false는 전체 글꼴이 사용됨을 의미합니다 (즉, 파일 크기가 커짐 : 4KB 대신 100KB). –
_why UTF-8 인코딩 또는 이와 유사한 것이 있습니까?_ 때문에 PDF 사양을 가지고 있지 않습니다. –