[英]itextsharp 5 writer.DirectContent creates 50% smaller file than PDFStamper
我真的很想使用使用PDFStamper的新方法,而不是使用(PdfWriter.GetInstance ... writer.DirectContent)的舊方法,但是使用舊方法創建的PDF文件的大小是使用新方法的1/2 。 兩種方法之間我缺少什么嗎?
//Old way using PdfWriter.GetInstance... writer.DirectContent
public static void AddHeaderTextLayer()
{
string HdrLeft = string.Empty;
string HdrRight = string.Empty;
string PageHdrName = "XHdr";
string NoOfPagesPadded = string.Empty;
string PageNoPadded = string.Empty;
int xLeft = 30;
int xRight = 100;
int xTop = 15;
string filename = "4_20140909.pdf";
PdfReader reader = new PdfReader(@"C:\!stuff\Junk\ChemWatchPDF\" + filename); // input file
using (var fileStream = new FileStream(@"C:\!stuff\Junk\ChemWatchPDF\" + filename.Replace(".pdf", "") + "_withHdrLTp.pdf", FileMode.Create, FileAccess.Write))
{
var document = new Document(reader.GetPageSizeWithRotation(1));
var writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
for (var i = 1; i <= reader.NumberOfPages; i++)
{
Rectangle pageRect = reader.GetPageSize(i);
document.NewPage();
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
var importedPage = writer.GetImportedPage(reader, i);
var contentByte = writer.DirectContent;
contentByte.AddTemplate(importedPage, 0, 0);
string SDSNo = "12345678";
HdrLeft = $"Company MSDS# {SDSNo}";
NoOfPagesPadded = (reader.NumberOfPages.ToString());
PageNoPadded = i.ToString();
HdrRight = $" Page {PageNoPadded} of {NoOfPagesPadded}";
contentByte.BeginLayer(new PdfLayer(PageHdrName + i.ToString(), writer));
contentByte.BeginText();
contentByte.SetFontAndSize(baseFont, 10);
contentByte.SetColorFill(LabColor.RED);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrLeft, pageRect.Left + xLeft, pageRect.Top - xTop, 0);
contentByte.EndText();
contentByte.BeginText();
contentByte.SetFontAndSize(baseFont, 10);
contentByte.SetColorFill(LabColor.RED);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrRight, pageRect.Right - xRight, pageRect.Top - xTop, 0);
contentByte.EndText();
contentByte.EndLayer();
}
document.Close();
writer.Close();
}
}
// New way using PDFStamper
public void Add()
{
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false);
string outPutFile = string.Empty;
var SingleLine = string.Empty;
string HdrLeft = string.Empty;
string HdrRight = string.Empty;
string PageHdrName = "xHdr";
string NoOfPagesPadded = string.Empty;
string PageNoPadded = string.Empty;
int xLeft = 30;
int xRight = 100;
int xTop = 15;
string filename = "4_20140909.pdf";
outPutFile = @"C:\!stuff\Junk\ChemWatchPDF\" + filename.Replace(".pdf", "") + "_withHdrLTStamp.pdf";
using (var newPDF = new FileStream(outPutFile, FileMode.Create, FileAccess.ReadWrite))
{
PdfReader reader = new PdfReader(@"C:\!stuff\Junk\ChemWatchPDF\" + filename); // input file
PdfStamper pdfStamper = new PdfStamper(reader, newPDF);
PdfLayer wmLayer = new PdfLayer(PageHdrName, pdfStamper.Writer);
for (int page = 1; page <= reader.NumberOfPages; page++)
{
PdfContentByte pdfContent = pdfStamper.GetOverContent(page);
Rectangle pageRect = reader.GetPageSize(page);
string SDSNo = "12345678";
HdrLeft = $"Company MSDS# {SDSNo}";
NoOfPagesPadded = (reader.NumberOfPages.ToString());
PageNoPadded = page.ToString();
HdrRight = $"Page {PageNoPadded} of {NoOfPagesPadded}";
pdfContent.BeginLayer(wmLayer);
pdfContent.BeginText();
pdfContent.SetFontAndSize(baseFont, 10);
pdfContent.SetColorFill(LabColor.RED);
pdfContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrLeft, pageRect.Left + xLeft, pageRect.Top - xTop, 0);
pdfContent.EndText();
pdfContent.BeginText();
pdfContent.SetFontAndSize(baseFont, 10);
pdfContent.SetColorFill(LabColor.RED);
pdfContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrRight, pageRect.Right - xRight, pageRect.Top - xTop, 0);
pdfContent.EndText();
pdfContent.EndLayer();
}
pdfStamper.Close();
}
}
}
}
您蓋章的副本(“較新方法”的輸出)包含一個結構樹 ,我認為該樹來自原始文檔。 它在“舊方法”的輸出中丟失了。
結構樹描述了文檔的邏輯結構。 它增加了文檔的可訪問性,並且在越來越多的國家和地區,文檔的存在成為法律要求。 因此,通常丟棄結構樹是一個壞主意。
結構樹本身由許多小的間接對象組成,如果您的PDF包含1000多個間接對象,它們的大小總計約為90KB。 此外,每個間接對象都需要一個20字節的交叉引用條目,在您的情況下,總計約為20KB。 這解釋了兩個輸出之間幾乎所有111KB的大小差異。
如果使用對象流和交叉引用流,則通常可以很好地壓縮結構樹。 因此,我建議您在iText中激活完全壓縮 ,使其使用對象流和交叉引用流:
PdfStamper pdfStamper = new PdfStamper(reader, newPDF);
pdfStamper.SetFullCompression();
pdfStamper.Writer.CompressionLevel = 9;
通過使用PdfReader/PdfStamper
結合這些設置簡單地處理大型PDF,而無需任何其他操作,我將文件的大小從234KB減少到133KB。
順便說一句,您將使用PdfWriter
的方法稱為調用,並將頁面導入稱為“舊方法”,而將PdfStamper
的方法PdfStamper
“新方法”。 實際上,至少從2003年開始,iText中就存在PdfStamper
類! 所以它不是真正的舊與新 ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.