iText Java处理PDF页面缩放时遇CMap缺失异常求助
解决iText处理PDF时的CMap缺失异常
问题原因
异常The CMap com/itextpdf/io/font/cmap/UniJIS-UTF16-H was not found是因为待处理的PDF包含日文字体,而iText核心模块(itext-kernel)未内置CJK(中日韩)相关的字符映射表(CMap)文件,这类资源需要单独引入itext7-fonts模块才能获取。
解决方案
1. 添加必要依赖
如果使用Maven,在pom.xml中补充itext7-fonts依赖(版本需与已用的iText核心模块版本一致):
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-fonts</artifactId> <version>你的iText版本号</version> </dependency>
若用Gradle,添加:
implementation 'com.itextpdf:itext7-fonts:你的iText版本号'
2. 确保打包时保留CMap资源
使用打包工具(如Maven Assembly、Spring Boot插件)时,需保证com/itextpdf/io/font/cmap/路径下的所有CMap文件被正确打包到最终产物中,避免资源丢失导致异常。
3. 临时应急方案(不推荐)
若无法添加itext7-fonts依赖,可临时修改scale方法,捕获CMap缺失异常并跳过对应页面的边界框计算,但这会影响缩放准确性:
void scale(com.itextpdf.kernel.pdf.PdfDocument pdfDocument, com.itextpdf.kernel.geom.Rectangle pageSize, com.itextpdf.kernel.geom.Rectangle pageBodySize) { for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) { com.itextpdf.kernel.pdf.PdfPage page = pdfDocument.getPage(i); // 页面旋转处理 if( page.getPageSizeWithRotation().getWidth() > page.getPageSizeWithRotation().getHeight() ) pdfDocument.getPage(i).put(com.itextpdf.kernel.pdf.PdfName.Rotate,PORTRAIT); if ( page.getRotation() == 90 ) pdfDocument.getPage(i).put(com.itextpdf.kernel.pdf.PdfName.Rotate,PORTRAIT); MarginFinder marginFinder = new MarginFinder(); com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor pdfCanvasProcessor = new com.itextpdf.kernel .pdf.canvas.parser.PdfCanvasProcessor(marginFinder); try { pdfCanvasProcessor.processPageContent(page); } catch (Exception e) { if (e.getMessage().contains("CMap com/itextpdf/io/font/cmap/UniJIS-UTF16-H was not found")) { System.err.printf("页面 %d 包含CJK字体,缺少CMap资源,跳过边界框计算%n", i); page.setMediaBox(pageSize); page.setCropBox(pageSize); continue; } throw e; } com.itextpdf.kernel.geom.Rectangle boundingBox = marginFinder.getBoundingBox(); if (boundingBox == null || boundingBox.getWidth() == 0 || boundingBox.getHeight() == 0) { System.err.printf("Não é possível dimensionar o conteúdo da página %d com a caixa delimitadora %s%n", i , boundingBox); continue; } else { List<Double> retornoScales = calcularFatorScale(pageBodySize,boundingBox); double scale = retornoScales.get(0); double xDiff = retornoScales.get(1); double yDiff = retornoScales.get(2); if( scale > 0.5 ){ com.itextpdf.kernel.geom.AffineTransform transform = com.itextpdf.kernel.geom.AffineTransform .getTranslateInstance(pageBodySize.getLeft() + xDiff, pageBodySize.getBottom() + yDiff); transform.scale(scale, scale); transform.translate(-boundingBox.getLeft(), -boundingBox.getBottom()); new com.itextpdf.kernel.pdf.canvas.PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDocument) .concatMatrix(transform); } } page.setMediaBox(pageSize); page.setCropBox(pageSize); } }
关键说明
itext7-fonts模块包含所有CJK相关的CMap文件与字体资源,是处理中日韩语言PDF的最优解决方案。- 跳过解析的方案仅为临时 workaround,会降低页面缩放的精准度,建议优先通过添加依赖解决问题。
内容的提问来源于stack exchange,提问作者Leo Castro
相关产品推荐
相关产品推荐

