PdfPCell 上的字体颜色会增加 PDF 文件的大小
Font Color on PdfPCell increases the size of PDF file
我用这种方式创建了一个字体。
Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, Color.WHITE);
然后在带有 Phrase 的 PdfPCell 中使用它。
PdfPCell hcell = new PdfPCell(new Phrase("Column A", tableHeaderFont));
我在每一页上显示 table header。
现在,如果我删除字体颜色,它会生成 PDF file of size 10 MB
,但是当提供颜色时,它会生成 size 24 MB
的 PDF 文件。 PDF文档大约有1400页。
有没有更好的方法来指定 PdfPCell 级别的字体颜色?
除此之外,当我尝试使用 PdfSmartCopy
合并这些 pdf 文档时,它需要大约 4 GB 的内存使用量。
iText
和 OpenPDF
我都试过了。
更新:
iText 5.5:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
当我使用 iText 5+ 的 BaseColor class 时,我得到相同大小的 pdf 文件,有或没有字体颜色。
Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, BaseColor.WHITE);
OpenPDF 1.3.20
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.3.20</version>
</dependency>
但是 OpenPDF 没有 BaseColor class 所以我必须在这里使用 Color.WHITE。
Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, Color.WHITE);
在OpenPDF 或 iText4[=67= 中,我们是否有 BaseColor class 的替代方案]?
更新 2:重现问题的示例用例。
OpenPDF Impl:PDF 文件大小约为 15 MB
import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class TestOpenPDF {
public static void main(String[] args) throws FileNotFoundException {
Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
Document.compress = false;
try {
PdfWriter.getInstance(document,
new FileOutputStream("AddBigTable_OpenPDF.pdf"));
document.open();
String[] bogusData = {"M0065920"};
int NumColumns = 1;
PdfPTable datatable = new PdfPTable(NumColumns);
datatable.getDefaultCell().setPadding(3);
datatable.getDefaultCell().setBorderWidth(2);
datatable.getDefaultCell().setHorizontalAlignment(
Element.ALIGN_CENTER);
Font tableHeaderFont = new Font(Font.HELVETICA, 20, Font.NORMAL, Color.WHITE);
PdfPCell header = new PdfPCell(new Phrase("Clock #", tableHeaderFont));
header.setBackgroundColor(Color.GRAY);
header.setPadding(3);
header.setBorderWidth(2);
header.setHorizontalAlignment(Element.ALIGN_CENTER);
datatable.addCell(header);
datatable.setHeaderRows(1); // this is the end of the table header
datatable.getDefaultCell().setBorderWidth(1);
for (int i = 1; i < 75000; i++) {
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(0.9f);
}
for (int x = 0; x < NumColumns; x++) {
datatable.addCell(bogusData[x]);
}
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(1);
}
}
document.add(datatable);
} catch (Exception de) {
de.printStackTrace();
}
document.close();
}
}
iText Impl:PDF 文件大小约为 8.5 MB
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class TestIText {
public static void main(String[] args) throws FileNotFoundException {
Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
Document.compress = false;
try {
PdfWriter.getInstance(document,
new FileOutputStream("AddBigTable_iText.pdf"));
document.open();
String[] bogusData = {"M0065920"};
int NumColumns = 1;
PdfPTable datatable = new PdfPTable(NumColumns);
datatable.getDefaultCell().setPadding(3);
datatable.getDefaultCell().setBorderWidth(2);
datatable.getDefaultCell().setHorizontalAlignment(
Element.ALIGN_CENTER);
Font tableHeaderFont = FontFactory.getFont(FontFactory.HELVETICA, 20, Font.NORMAL, BaseColor.WHITE);
PdfPCell header = new PdfPCell(new Phrase("Clock #", tableHeaderFont));
header.setBackgroundColor(BaseColor.GRAY);
header.setPadding(3);
header.setBorderWidth(2);
header.setHorizontalAlignment(Element.ALIGN_CENTER);
datatable.addCell(header);
datatable.setHeaderRows(1); // this is the end of the table header
datatable.getDefaultCell().setBorderWidth(1);
for (int i = 1; i < 75000; i++) {
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(0.9f);
}
for (int x = 0; x < NumColumns; x++) {
datatable.addCell(bogusData[x]);
}
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(1);
}
}
document.add(datatable);
} catch (Exception de) {
de.printStackTrace();
}
document.close();
}
}
从共享的片段中,我可以了解到使用了iText 2
。如果可能的话,最好重新考虑这样的选择,因为 iText 2
已经超过 10 年了,可能有很多功能和安全问题并且不再维护。
我建议更新到 iText 7
。虽然我没有你的代码,因此无法证明在你的情况下设置颜色不会使 PDF 的大小变得更大,但我创建了以下示例来证明应该没有问题:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
for (int i = 0; i < 10000; i++) {
doc.add(new Paragraph("Hello World")/*.setFontColor(ColorConstants.RED)*/);
}
doc.close();
启用字体颜色后生成的PDF大小为161Kb;禁用字体颜色的结果 PDF 的大小为 160Kb(这是完全预期的,因为启用颜色意味着将相应的指令写入 PDF:那里有 10k 条指令,因此相差 1Kb)。
最新版本的 OpenPDF 1.3.25 已解决此问题。我用的是旧版本。
我用这种方式创建了一个字体。
Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, Color.WHITE);
然后在带有 Phrase 的 PdfPCell 中使用它。
PdfPCell hcell = new PdfPCell(new Phrase("Column A", tableHeaderFont));
我在每一页上显示 table header。
现在,如果我删除字体颜色,它会生成 PDF file of size 10 MB
,但是当提供颜色时,它会生成 size 24 MB
的 PDF 文件。 PDF文档大约有1400页。
有没有更好的方法来指定 PdfPCell 级别的字体颜色?
除此之外,当我尝试使用 PdfSmartCopy
合并这些 pdf 文档时,它需要大约 4 GB 的内存使用量。
iText
和 OpenPDF
我都试过了。
更新:
iText 5.5:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
当我使用 iText 5+ 的 BaseColor class 时,我得到相同大小的 pdf 文件,有或没有字体颜色。
Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, BaseColor.WHITE);
OpenPDF 1.3.20
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.3.20</version>
</dependency>
但是 OpenPDF 没有 BaseColor class 所以我必须在这里使用 Color.WHITE。
Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, Color.WHITE);
在OpenPDF 或 iText4[=67= 中,我们是否有 BaseColor class 的替代方案]?
更新 2:重现问题的示例用例。
OpenPDF Impl:PDF 文件大小约为 15 MB
import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class TestOpenPDF {
public static void main(String[] args) throws FileNotFoundException {
Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
Document.compress = false;
try {
PdfWriter.getInstance(document,
new FileOutputStream("AddBigTable_OpenPDF.pdf"));
document.open();
String[] bogusData = {"M0065920"};
int NumColumns = 1;
PdfPTable datatable = new PdfPTable(NumColumns);
datatable.getDefaultCell().setPadding(3);
datatable.getDefaultCell().setBorderWidth(2);
datatable.getDefaultCell().setHorizontalAlignment(
Element.ALIGN_CENTER);
Font tableHeaderFont = new Font(Font.HELVETICA, 20, Font.NORMAL, Color.WHITE);
PdfPCell header = new PdfPCell(new Phrase("Clock #", tableHeaderFont));
header.setBackgroundColor(Color.GRAY);
header.setPadding(3);
header.setBorderWidth(2);
header.setHorizontalAlignment(Element.ALIGN_CENTER);
datatable.addCell(header);
datatable.setHeaderRows(1); // this is the end of the table header
datatable.getDefaultCell().setBorderWidth(1);
for (int i = 1; i < 75000; i++) {
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(0.9f);
}
for (int x = 0; x < NumColumns; x++) {
datatable.addCell(bogusData[x]);
}
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(1);
}
}
document.add(datatable);
} catch (Exception de) {
de.printStackTrace();
}
document.close();
}
}
iText Impl:PDF 文件大小约为 8.5 MB
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class TestIText {
public static void main(String[] args) throws FileNotFoundException {
Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
Document.compress = false;
try {
PdfWriter.getInstance(document,
new FileOutputStream("AddBigTable_iText.pdf"));
document.open();
String[] bogusData = {"M0065920"};
int NumColumns = 1;
PdfPTable datatable = new PdfPTable(NumColumns);
datatable.getDefaultCell().setPadding(3);
datatable.getDefaultCell().setBorderWidth(2);
datatable.getDefaultCell().setHorizontalAlignment(
Element.ALIGN_CENTER);
Font tableHeaderFont = FontFactory.getFont(FontFactory.HELVETICA, 20, Font.NORMAL, BaseColor.WHITE);
PdfPCell header = new PdfPCell(new Phrase("Clock #", tableHeaderFont));
header.setBackgroundColor(BaseColor.GRAY);
header.setPadding(3);
header.setBorderWidth(2);
header.setHorizontalAlignment(Element.ALIGN_CENTER);
datatable.addCell(header);
datatable.setHeaderRows(1); // this is the end of the table header
datatable.getDefaultCell().setBorderWidth(1);
for (int i = 1; i < 75000; i++) {
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(0.9f);
}
for (int x = 0; x < NumColumns; x++) {
datatable.addCell(bogusData[x]);
}
if (i % 2 == 1) {
datatable.getDefaultCell().setGrayFill(1);
}
}
document.add(datatable);
} catch (Exception de) {
de.printStackTrace();
}
document.close();
}
}
从共享的片段中,我可以了解到使用了iText 2
。如果可能的话,最好重新考虑这样的选择,因为 iText 2
已经超过 10 年了,可能有很多功能和安全问题并且不再维护。
我建议更新到 iText 7
。虽然我没有你的代码,因此无法证明在你的情况下设置颜色不会使 PDF 的大小变得更大,但我创建了以下示例来证明应该没有问题:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
for (int i = 0; i < 10000; i++) {
doc.add(new Paragraph("Hello World")/*.setFontColor(ColorConstants.RED)*/);
}
doc.close();
启用字体颜色后生成的PDF大小为161Kb;禁用字体颜色的结果 PDF 的大小为 160Kb(这是完全预期的,因为启用颜色意味着将相应的指令写入 PDF:那里有 10k 条指令,因此相差 1Kb)。
最新版本的 OpenPDF 1.3.25 已解决此问题。我用的是旧版本。