使用 iTextSharp 将文本添加到内存流中的现有多页 PDF 文档
Posted
技术标签:
【中文标题】使用 iTextSharp 将文本添加到内存流中的现有多页 PDF 文档【英文标题】:Adding text to existing multipage PDF document in memorystream using iTextSharp 【发布时间】:2014-07-06 12:13:06 【问题描述】:我正在尝试使用 iTextSharp 向现有 PDF 文件添加文本。我一直在阅读很多帖子,包括popular thread here。
我有一些不同:
我的 PDF 有 X 页 我希望将所有内容都保存在内存中,并且永远不会在我的文件系统中存储文件所以我尝试修改代码,让它接受一个字节数组并返回一个字节数组。我已经走到这一步了:
代码编译运行 我的输出字节数组的长度不同于我的输入字节数组我的问题:
当我稍后存储修改后的字节数组并在我的 PDF 阅读器中打开它时,我看不到我添加的文本我不明白为什么。从我看到的每篇 *** 帖子中,我都会这样做。使用DirectContent
,我使用BeginText
并写一个文本。但是,无论我如何移动位置,我都看不到它。
知道我的代码中缺少什么吗?
public static byte[] WriteIdOnPdf(byte[] inPDF, string str)
byte[] finalBytes;
// open the reader
using (PdfReader reader = new PdfReader(inPDF))
Rectangle size = reader.GetPageSizeWithRotation(1);
using (Document document = new Document(size))
// open the writer
using (MemoryStream ms = new MemoryStream())
using (PdfWriter writer = PdfWriter.GetInstance(document, ms))
document.Open();
for (var i = 1; i <= reader.NumberOfPages; 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.BeginText();
contentByte.SetFontAndSize(baseFont, 18);
var multiLineString = "Hello,\r\nWorld!";
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, multiLineString,100, 200, 0);
contentByte.EndText();
contentByte.AddTemplate(importedPage, 0, 0);
document.Close();
ms.Close();
writer.Close();
reader.Close();
finalBytes = ms.ToArray();
return finalBytes;
【问题讨论】:
在关闭 writer 之前关闭内存流。但是关闭期间的作者试图向流中写入一些东西。您首先将添加的内容写在目标页面上,然后将原始页面放在其上方。因此,可以覆盖添加。 【参考方案1】:下面的代码展示了一个在内存中创建 PDF 然后在内存中执行第二遍的完整示例。它执行@mkl 所说的操作并在尝试从流中获取原始字节之前关闭所有 iText 部分。它还使用GetOverContent()
在前一个 pdf 的“顶部”绘制。更多详细信息请参见代码 cmets。
//Bytes will hold our final PDFs
byte[] bytes;
//Create an in-memory PDF
using (var ms = new MemoryStream())
using (var doc = new Document())
using (var writer = PdfWriter.GetInstance(doc, ms))
doc.Open();
//Create a bunch of pages and add text, nothing special here
for (var i = 1; i <= 10; i++)
doc.NewPage();
doc.Add(new Paragraph(String.Format("First Pass - Page 0", i)));
doc.Close();
//Right before disposing of the MemoryStream grab all of the bytes
bytes = ms.ToArray();
//Another in-memory PDF
using (var ms = new MemoryStream())
//Bind a reader to the bytes that we created above
using (var reader = new PdfReader(bytes))
//Store our page count
var pageCount = reader.NumberOfPages;
//Bind a stamper to our reader
using (var stamper = new PdfStamper(reader, ms))
//Setup a font to use
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
//Loop through each page
for (var i = 1; i <= pageCount; i++)
//Get the raw PDF stream "on top" of the existing content
var cb = stamper.GetOverContent(i);
//Draw some text
cb.BeginText();
cb.SetFontAndSize(baseFont, 18);
cb.ShowText(String.Format("Second Pass - Page 0", i));
cb.EndText();
//Once again, grab the bytes before closing things out
bytes = ms.ToArray();
//Just to see the final results I'm writing these bytes to disk but you could do whatever
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
System.IO.File.WriteAllBytes(testFile, bytes);
【讨论】:
以上是关于使用 iTextSharp 将文本添加到内存流中的现有多页 PDF 文档的主要内容,如果未能解决你的问题,请参考以下文章
使用 itextsharp 将图像 html 旁边的文本放置到 pdf