使用iText生成PDF时,如果需要多次切换字体,则文件大小会变得太大

使用iText生成PDF时,如果需要多次切换字体,则文件大小会变得太大,pdf,fonts,itext,itext7,Pdf,Fonts,Itext,Itext7,我的PDF文件中有一个部分,我需要使用一种字体作为unicode符号,其余部分应该是不同的字体。(类似于“1.a2.b3.c”,其中“1.”是unicode符号/字体,“a”是另一种字体)我遵循了Bruno在这里描述的方法:生成PDF效果很好。问题是PDF的文件大小从20MB左右变为100MB左右,而只使用一种字体和一个文本元素。本节在文档中重复使用了数千次。我想知道是否有办法减少字体切换的影响,或者以某种方式减少整个文档的文件大小 样式创建伪代码: Style style1 = new Sty

我的PDF文件中有一个部分,我需要使用一种字体作为unicode符号,其余部分应该是不同的字体。(类似于“1.a2.b3.c”,其中“1.”是unicode符号/字体,“a”是另一种字体)我遵循了Bruno在这里描述的方法:生成PDF效果很好。问题是PDF的文件大小从20MB左右变为100MB左右,而只使用一种字体和一个文本元素。本节在文档中重复使用了数千次。我想知道是否有办法减少字体切换的影响,或者以某种方式减少整个文档的文件大小

样式创建伪代码:

Style style1 = new Style();
Style style2 = new Style();
PdfFont font1 = PdfFontFactory.createFont(FontProgramFactory.createFont(fontFile1), PdfEncodings.IDENTITY_H, true);
style1.setFont(font1).setFontSize(8f).setFontColor(Color.DARK_GRAY);
PdfFont font2 = PdfFontFactory.createFont(FontProgramFactory.createFont(fontFile2), "", false);
style2.setFont(font2).setFontSize(8f).setFontColor(Color.DARK_GRAY);
Div div = new Div().setPaddingLeft(3).setMarginBottom(0).setKeepTogether(true);
Paragraph paragraph = new Paragraph();
loop up to 25 times: {
    Text unicodeText = new Text(unicodeSymbol + " ").addStyle(style1);
    paragraph.add(unicodeText);
    Text plainText = new Text(plainText + " ").addStyle(style2);
    paragraph.add(plainText);
}
div.add(paragraph);
编写文本/段落伪代码:

Style style1 = new Style();
Style style2 = new Style();
PdfFont font1 = PdfFontFactory.createFont(FontProgramFactory.createFont(fontFile1), PdfEncodings.IDENTITY_H, true);
style1.setFont(font1).setFontSize(8f).setFontColor(Color.DARK_GRAY);
PdfFont font2 = PdfFontFactory.createFont(FontProgramFactory.createFont(fontFile2), "", false);
style2.setFont(font2).setFontSize(8f).setFontColor(Color.DARK_GRAY);
Div div = new Div().setPaddingLeft(3).setMarginBottom(0).setKeepTogether(true);
Paragraph paragraph = new Paragraph();
loop up to 25 times: {
    Text unicodeText = new Text(unicodeSymbol + " ").addStyle(style1);
    paragraph.add(unicodeText);
    Text plainText = new Text(plainText + " ").addStyle(style2);
    paragraph.add(plainText);
}
div.add(paragraph);
这种文字/段落的书写已经进行了数千次,构成了文档的大部分。基本上,文档由数千个具有相应代码的“建筑”组成,这些代码具有类别。我需要将该类别的索引作为unicode符号,然后在该建筑的段落中使用所有相应的代码

以下是可复制代码:

    float offSet = 50;
    Integer leading = 10;
    DateFormat format = new SimpleDateFormat("yyyy_MM_dd_kkmmss");
    String formattedDate = format.format(new Date());
    String path = "/tmp/testing_pdf_"+formattedDate + ".pdf";
    File targetPdfFile = new File(path);
    PdfWriter writer = new PdfWriter(path, new WriterProperties().addXmpMetadata());
    PdfDocument pdf = new PdfDocument(writer);
    pdf.setTagged();
    PageSize pageSize = PageSize.LETTER;
    Document document = new Document(pdf, pageSize);
    document.setMargins(offSet, offSet, offSet, offSet);
    byte[] font1file = IOUtils.toByteArray(FileUtility.getInputStreamFromClassPath("fonts/Garamond-Premier-Pro-Regular.ttf"));
    byte[] font2file = IOUtils.toByteArray(FileUtility.getInputStreamFromClassPath("fonts/Quivira.otf"));
    PdfFont font1 = PdfFontFactory.createFont(FontProgramFactory.createFont(font1file), "", true);
    PdfFont font2 = PdfFontFactory.createFont(FontProgramFactory.createFont(font2file), PdfEncodings.IDENTITY_H, true);
    Style style1 = new Style().setFont(font1).setFontSize(8f).setFontColor(Color.DARK_GRAY);
    Style style2 = new Style().setFont(font2).setFontSize(8f).setFontColor(Color.DARK_GRAY);
    float columnGap = 5;
    float columnWidth = (pageSize.getWidth() - offSet * 2 - columnGap * 2) / 3;
    float columnHeight = pageSize.getHeight() - offSet * 2;
    Rectangle[] columns = {
            new Rectangle(offSet, offSet, columnWidth, columnHeight),
            new Rectangle(offSet + columnWidth + columnGap, offSet, columnWidth, columnHeight),
            new Rectangle(offSet + columnWidth * 2 + columnGap * 2, offSet, columnWidth, columnHeight)};
    document.setRenderer(new ColumnDocumentRenderer(document, columns));
    for (int j = 0; j < 5000; j++) {
        Div div = new Div().setPaddingLeft(3).setMarginBottom(0).setKeepTogether(true);
        Paragraph paragraph = new Paragraph().setFixedLeading(leading);
//            StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 26; i++) {
            paragraph.add(new Text("\u3255 ").addStyle(style2));
            paragraph.add(new Text("test ").addStyle(style1));
//                stringBuilder.append("\u3255 ").append(" test ");
        }
//            paragraph.add(stringBuilder.toString()).addStyle(style2);

        div.add(paragraph);
        document.add(div);
    }
    document.close();
float offSet=50;
整数前导=10;
DateFormat格式=新的SimpleDataFormat(“yyyy_-MM_-dd_-kkmms”);
字符串formattedDate=format.format(新日期());
字符串路径=“/tmp/testing\u pdf\u”+formattedDate+”.pdf”;
File targetPdfFile=新文件(路径);
PdfWriter writer=new PdfWriter(路径,new WriterProperties().addXmpMetadata());
PdfDocument pdf=新PdfDocument(编写器);
pdf.settaged();
PageSize PageSize=PageSize.LETTER;
文档=新文档(pdf,页面大小);
单据.设置页边距(抵销,抵销,抵销,抵销);
byte[]font1file=IOUtils.toByteArray(FileUtility.getInputStreamFromClassPath(“font/Garamond Premier Pro Regular.ttf”);
byte[]font2file=IOUtils.toByteArray(FileUtility.getInputStreamFromClassPath(“font/quivila.otf”);
Pdfont font1=PdfontFactory.createFont(FontProgramFactory.createFont(font1file)),true;
PdfFont font2=PdfFontFactory.createFont(fontprogrammafactory.createFont(font2file),PdfEncodings.IDENTITY_H,true);
Style style1=新样式().setFont(font1).setFontSize(8f).setFontColor(Color.深灰色);
Style style2=新样式().setFont(font2).setFontSize(8f).setFontColor(Color.深灰色);
浮柱间隙=5;
float columnWidth=(pageSize.getWidth()-offSet*2-columnGap*2)/3;
float columnHeight=pageSize.getHeight()-偏移量*2;
矩形[]列={
新矩形(偏移、偏移、列宽、列高),
新矩形(偏移量+列宽+列间距、偏移量、列宽、列高),
新矩形(偏移量+列宽*2+列间距*2,偏移量,列宽,列高)};
setRenderer(新的ColumnDocumentRenderer(文档,列));
对于(int j=0;j<5000;j++){
Div Div=new Div().setPaddingLeft(3).setMarginBottom(0).setKeepTogether(true);
段落=新段落();
//StringBuilder StringBuilder=新的StringBuilder();
对于(int i=0;i<26;i++){
添加(新文本(“\u3255”)。添加样式(样式2));
添加(新文本(“测试”)。添加样式(样式1));
//stringBuilder.append(“\u3255”).append(“测试”);
}
//段落.add(stringBuilder.toString()).addStyle(style2);
第2节增补(第2段);
文件.增补(div);
}
document.close();
在创建可复制代码时,我发现这与被标记的文档有关。如果删除将其标记为已标记的行,则会大大减小文件大小


您还可以通过使用注释掉的字符串生成器(使用一种字体而不是两种字体)来减小文件大小。(注释掉for循环中的两个“段落.添加”)这反映了我代码中的问题。

问题不在于字体本身。问题源于您正在创建带标签的PDF。带标签的文档中有很多PDF对象,需要在文件中留出大量空间

我无法复制您的20MB与100MB结果。在我的机器上,无论是使用一种字体还是使用两种字体,但使用两个
文本
元素,生成的文件大小约为44MB

要在创建大型标记文档时压缩文件,应使用完全压缩模式,该模式压缩所有PDF对象,而不仅仅是流

要激活完全压缩模式,请使用
WriterProperties
创建一个
PdfWriter
实例:

PdfWriter writer = new PdfWriter(outFileName, 
                  new WriterProperties().setFullCompressionMode(true));
此设置将我的文件大小从>40MB减少到~5MB


请注意,您正在使用iText
7.0.x
,而
7.1.x
行已经发布,现在是iText的主线,因此我建议您更新到最新版本。

问题不在于字体本身。问题源于您正在创建带标签的PDF。带标签的文档中有很多PDF对象,需要在文件中留出大量空间

我无法复制您的20MB与100MB结果。在我的机器上,无论是使用一种字体还是使用两种字体,但使用两个
文本
元素,生成的文件大小约为44MB

要在创建大型标记文档时压缩文件,应使用完全压缩模式,该模式压缩所有PDF对象,而不仅仅是流

要激活完全压缩模式,请使用
WriterProperties
创建一个
PdfWriter
实例:

PdfWriter writer = new PdfWriter(outFileName, 
                  new WriterProperties().setFullCompressionMode(true));
此设置将我的文件大小从>40MB减少到~5MB


请注意,您使用的是iText
7.0.x
,而
7.1.x
行已经发布,现在是iText的主线,因此我建议您更新到最新版本。

听起来像是在嵌入完整版本