我使用PDFBOX版本2将两个PDF文件合并为一个。 第一个获得字体:
DECLARE @string varchar(100) = 'abc, bcd, hbg'
while(contains(@string ,'abc'))
BEGIN
///
END
和第二个:
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
XXMGEM+Arial-BoldMT TrueType WinAnsi yes yes yes 15 0
XXMGEM+ArialMT TrueType WinAnsi yes yes yes 19 0
XXMGEM+ArialMT CID TrueType Identity-H yes yes yes 27 0
XXMGEM+ArialNarrow-Bold TrueType WinAnsi yes yes yes 40 0
XXMGEM+ArialNarrow TrueType WinAnsi yes yes yes 44 0
合并后,会发生以下情况:
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
UNTWVR+HelveticaLTCom-Roman CID TrueType Identity-H yes yes yes 25 0
UNTYID+HelveticaLTCom-Bold CID TrueType Identity-H yes yes yes 26 0
UNTZUP+ArialMT CID TrueType Identity-H yes yes yes 27 0
UNUBHB+Arial-BoldMT CID TrueType Identity-H yes yes yes 28 0
Helvetica-Bold Type 1 WinAnsi no no no 29 0
UNXPUH+HelveticaLTCom-Roman CID TrueType Identity-H yes yes yes 50 0
UNXRGT+HelveticaLTCom-Bold CID TrueType Identity-H yes yes yes 51 0
UNXSTF+ArialMT CID TrueType Identity-H yes yes yes 52 0
UNXUFR+Arial-BoldMT CID TrueType Identity-H yes yes yes 53 0
我的Java代码:
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
SRWYVL+HelveticaLTCom-Roman CID TrueType Identity-H yes yes yes 420 0
SRXAHX+HelveticaLTCom-Bold CID TrueType Identity-H yes yes yes 421 0
SRXBUJ+ArialMT CID TrueType Identity-H yes yes yes 422 0
SRXDGV+Arial-BoldMT CID TrueType Identity-H yes yes yes 423 0
Helvetica-Bold Type 1 WinAnsi no no no 424 0
SRWYVL+HelveticaLTCom-Roman CID TrueType Identity-H yes yes yes 425 0
SRXAHX+HelveticaLTCom-Bold CID TrueType Identity-H yes yes yes 426 0
SRXBUJ+ArialMT CID TrueType Identity-H yes yes yes 427 0
SRXDGV+Arial-BoldMT CID TrueType Identity-H yes yes yes 428 0
SRWYVL+ArialMT CID TrueType Identity-H yes yes yes 429 0
SRXAHX+HelveticaLTCom-Roman CID TrueType Identity-H yes yes yes 430 0
SRXBUJ+HelveticaLTCom-Bold CID TrueType Identity-H yes yes yes 431 0
SRXDGV+Arial-BoldMT CID TrueType Identity-H yes yes yes 432 0
WDEGAT+Arial-BoldMT TrueType WinAnsi yes yes yes 436 0
GSEDXU+ArialMT TrueType WinAnsi yes yes yes 437 0
Arial TrueType WinAnsi yes no no 416 0
ZapfDingbats TrueType WinAnsi yes no yes 419 0
ArialNarrow TrueType WinAnsi yes no no 417 0
ACHRDX+ZapfDingbats TrueType WinAnsi yes yes yes 618 0
ACHRDX+ZapfDingbats TrueType WinAnsi yes yes yes 619 0
ACHRDX+ZapfDingbats TrueType WinAnsi yes yes yes 620 0
ACHRDX+ZapfDingbats TrueType WinAnsi yes yes yes 621 0
ACHRDX+ZapfDingbats TrueType WinAnsi yes yes yes 622 0
GSEDXU+ArialNarrow-Bold TrueType WinAnsi yes yes yes 560 0
NVGLHQ+ArialNarrow TrueType WinAnsi yes yes yes 561 0
KWHHMM+ArialMT CID TrueType Identity-H yes yes yes 578 0
问题是来自第三方供应商的Api与此字体有问题。 所以:我在做什么错了,我该如何删除未使用和加倍的字体?
答案 0 :(得分:4)
“重复”问题似乎来自多个页面,因为每个页面都包含自己的字体元数据。如果您遍历页面并获取字体名称,那么如果在多个页面中使用了字体,您将在输出中看到重复的文字。
问题的细节似乎有些错误。两个源文件都没有ZapfDingbats
字体,那么它是从哪里来的到合并文档中?
首先,我编写了一些辅助方法:
static String mergePdfs(InputStream is1, InputStream is2) throws IOException {
PDFMergerUtility pdfMerger = new PDFMergerUtility();
pdfMerger.addSource(is1);
pdfMerger.addSource(is2);
String destFile = System.getProperty("java.io.tmpdir") + System.nanoTime() + ".pdf";
pdfMerger.setDestinationFileName(destFile);
pdfMerger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
return destFile;
}
static List<String> getFontNames(PDDocument doc) throws IOException {
List<String> result = new ArrayList<>();
for (int i=0; i < doc.getNumberOfPages(); i++){
PDPage page = doc.getPage(i);
PDResources res = page.getResources();
for (COSName fontName : res.getFontNames()) {
result.add(res.getFont(fontName).toString());
}
}
return result;
}
然后,我创建了3个测试PDF文档。前两个test-pdf-1.pdf
和test-pdf-2.pdf
分别包含一页,并使用相同的两种字体:PDTrueTypeFont BAAAAA+ArialMT
和PDTrueTypeFont CAAAAA+Roboto-Black
。第三个test-pdf-3.pdf
包含前两个文档的2页,并且是使用文本编辑器而非PDFBox创建的。
然后添加以下测试代码:
Class clazz = Test.class;
String src1, src2, src3;
src1 = "/test-pdf-1.pdf";
src2 = "/test-pdf-2.pdf";
src3 = "/test-pdf-3.pdf";
InputStream is1, is2, is3;
is1 = clazz.getResourceAsStream(src1);
is2 = clazz.getResourceAsStream(src2);
String merged = mergePdfs(is1, is2);
PDDocument doc1, doc2, doc3, doc4;
is1 = clazz.getResourceAsStream(src1);
doc1 = PDDocument.load(is1);
is2 = clazz.getResourceAsStream(src2);
doc2 = PDDocument.load(is2);
is3 = clazz.getResourceAsStream(src3);
doc3 = PDDocument.load(is3);
doc4 = PDDocument.load(new File(merged));
System.out.println(src1 + " >\n\t" + getFontNames(doc1));
System.out.println(src2 + " >\n\t" + getFontNames(doc2));
System.out.println(src3 + " >\n\t" + getFontNames(doc3));
System.out.println(merged + " >\n\t" + getFontNames(doc4));
输出如下(为了便于阅读和比较,我将最后一个文件名截短了):
/test-pdf-1.pdf >
[PDTrueTypeFont BAAAAA+ArialMT, PDTrueTypeFont CAAAAA+Roboto-Black]
/test-pdf-2.pdf >
[PDTrueTypeFont BAAAAA+ArialMT, PDTrueTypeFont CAAAAA+Roboto-Black]
/test-pdf-3.pdf >
[PDTrueTypeFont BAAAAA+ArialMT, PDTrueTypeFont CAAAAA+Roboto-Black, PDTrueTypeFont BAAAAA+ArialMT, PDTrueTypeFont CAAAAA+Roboto-Black]
C:\Temp\..9.pdf >
[PDTrueTypeFont BAAAAA+ArialMT, PDTrueTypeFont CAAAAA+Roboto-Black, PDTrueTypeFont BAAAAA+ArialMT, PDTrueTypeFont CAAAAA+Roboto-Black]
您可以看到通过PDFBox合并创建的文件“ C:\ temp \ 7193671804393899.pdf”(在输出中为便于阅读而缩写),以及通过以下方式创建的文件“ test-pdf-3.pdf”编辑器的字体输出相同,每种字体显示两次,每页显示一次。
在Acrobat Reader中打开合并的文件,确认仅存在一个字体副本:
答案 1 :(得分:0)
由于无法找到或使用Pdf中嵌入的现有字体,因此合并程序将提供自己的替换字体。 您必须重写代码并使用特定的字体。 从pdf提取所有字体 然后合并它们,确保使用相同的字体。
尝试使用不会对第三方造成任何问题的系统字体 自定义字体始终是一个问题。 某些API不会使用任何未签名的字体。
检查此字体 名称类型编码emb sub uni对象ID
XXMGEM + Arial-BoldMT TrueType WinAnsi是是是15 0
该字体在第一个文件中,但将它们组合后会丢失该字体。