PDFBox生成PDF在pdf.js中部分符号渲染异常问题排查
PDFBox生成的PDF在pdf.js中无法正确渲染反引号、单引号等符号
我使用PDFBox生成PDF文件后,在Firefox浏览器的pdf.js中查看时,文本字段内的反引号(`)和单引号(')等符号无法正确渲染,但在Acrobat和Chrome浏览器中显示完全正常。我分别测试了嵌入Poppins字体和Arial字体的PDF文件,二者均出现相同的异常表现。
显示效果对比
- Acrobat中的正常显示:

- pdf.js中的异常显示:

我不确定这是pdf.js的固有限制,还是我生成PDF的代码存在问题,希望能确认问题根源。
相关代码
创建文本框的代码
public static void createTextbox(PDDocument doc, int pageIndex, PDRectangle rect, String fieldName, String fontPath) throws Exception { PDPage page = doc.getPage(pageIndex); // Add a new AcroForm and add that to the document PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm(); if (acroForm == null) { acroForm = new PDAcroForm(doc); doc.getDocumentCatalog().setAcroForm(acroForm); } if(acroForm.getFields() instanceof AbstractList){ acroForm.setFields(new ArrayList<>()); } PDResources resources = new PDResources(); acroForm.setDefaultResources(resources); // set custom font here, else the non embeded HELV will be used when u call to setNeedAppearances(true) PDType0Font f = PDType0Font.load(doc, new File(fontPath)); String customFontNameToMatch = f.getFontDescriptor().getFontName(); String fontName = null; PDFont customFont = null; Iterator<COSName> fontIte = acroForm.getDefaultResources().getFontNames().iterator(); while(fontIte.hasNext()){ COSName fcn = fontIte.next(); if(acroForm.getDefaultResources().getFont(fcn).getName().equals(customFontNameToMatch)){ fontName = fcn.getName(); customFont = acroForm.getDefaultResources().getFont(fcn); break; } } // font not embedded, embed it if (fontName == null){ customFont = PDTrueTypeFont.load(doc, new File(fontPath), StandardEncoding.INSTANCE); fontName = acroForm.getDefaultResources().add(customFont).getName(); } String defApp = String.format("/%s 0 Tf 0 0 0 rg", fontName); // Add a form field to the form. PDTextField textBox = new PDTextField(acroForm); textBox.setPartialName(fieldName); textBox.setReadOnly(true); textBox.setDefaultAppearance(defApp); textBox.setMultiline(true); // Specify the widget annotation associated with the field PDAnnotationWidget widget = textBox.getWidgets().get(0); widget.setRectangle(rect); widget.setPage(page); widget.getCOSObject().setNeedToBeUpdated(true); acroForm.setNeedAppearances(true); // make sure the widget annotation is visible on screen and paper widget.setPrinted(true); // Add the widget annotation to the page page.getAnnotations().add(widget); // set the alignment ("quadding") textBox.setQ(PDVariableText.QUADDING_LEFT); textBox.setDoNotScroll(true); textBox.getCOSObject().setNeedToBeUpdated(true); acroForm.getFields().add(textBox); acroForm.getCOSObject().setNeedToBeUpdated(true); page.getCOSObject().setNeedToBeUpdated(true); }
调用createTextbox()后执行doc.saveIncremental(baos);
填充文本框的代码
public static void fillTextBox(PDDocument doc, String fieldName, String fontPath, String text) throws Exception { // get the document catalog PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm(); // as there might not be an AcroForm entry a null check is necessary if (acroForm != null) { // Retrieve an individual field and set its value. PDTextField field = (PDTextField) acroForm.getField(fieldName); // set custom font PDType0Font f = PDType0Font.load(doc, new File(fontPath)); String customFontNameToMatch = f.getFontDescriptor().getFontName(); String fontName = null; PDFont customFont = null; Iterator<COSName> fontIte = acroForm.getDefaultResources().getFontNames().iterator(); while(fontIte.hasNext()){ COSName fcn = fontIte.next(); if(acroForm.getDefaultResources().getFont(fcn).getName().equals(customFontNameToMatch)){ fontName = fcn.getName(); customFont = acroForm.getDefaultResources().getFont(fcn); break; } } // font not embedded, embed it if (fontName == null){ customFont = PDTrueTypeFont.load(doc, new File(fontPath), StandardEncoding.INSTANCE); fontName = acroForm.getDefaultResources().add(customFont).getName(); } String defApp = String.format("/%s 0 Tf 0 0 0 rg", fontName); field.setDefaultAppearance(defApp); field.setMultiline(true); field.setReadOnly(true); field.setValue(text); PDAnnotationWidget widget = field.getWidgets().get(0); widget.setReadOnly(true); widget.setLocked(true); widget.getCOSObject().setNeedToBeUpdated(true); } }
调用fillTextBox()后执行doc.saveIncremental(baos);
使用的依赖版本
- pdfbox(Maven):3.0.4
- Java版本:21
内容的提问来源于stack exchange,提问作者rec7y33
相关产品推荐
相关产品推荐

