PDFBOX:合并添加未使用的字体,如何将其删除

时间:2018-11-15 09:27:12

标签: java pdfbox

我使用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与此字体有问题。 所以:我在做什么错了,我该如何删除未使用和加倍的字体?

2 个答案:

答案 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.pdftest-pdf-2.pdf分别包含一页,并使用相同的两种字体:PDTrueTypeFont BAAAAA+ArialMTPDTrueTypeFont 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中打开合并的文件,确认仅存在一个字体副本:

C:\temp\7193671804393899.pdf Properties > Fonts

答案 1 :(得分:0)

由于无法找到或使用Pdf中嵌入的现有字体,因此合并程序将提供自己的替换字体。 您必须重写代码并使用特定的字体。 从pdf提取所有字体 然后合并它们,确保使用相同的字体。

尝试使用不会对第三方造成任何问题的系统字体 自定义字体始终是一个问题。 某些API不会使用任何未签名的字体。

检查此字体 名称类型编码emb sub uni对象ID


XXMGEM + Arial-BoldMT TrueType WinAnsi是是是15 0

该字体在第一个文件中,但将它们组合后会丢失该字体。