将项目添加到现有PDF的正确方法是什么?方法GetFileBytes 从磁盘读取PDF并转换为数组,这工作正常,但是 结果文件NP.PDF与原始文件完全相同。我其实想要 添加条形码,但想先尝试使用简单的项目。
Byte[] bytes = GetFileBytes();
Document document = new Document();
MemoryStream ms = new MemoryStream(bytes);
PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
document.Add(new Paragraph("First Paragraph"));
document.Add(new Paragraph("Second Paragraph"));
//document.Close();
ms.Position = 0;
File.WriteAllBytes(@"e:\NP.pdf", (Byte[])ms.ToArray());
答案 0 :(得分:5)
这就是我过去的做法。您需要为PDF编写器使用新流,并将原始PDF内容添加到新文档中。这可能不是最好或最有效的方式,这正是我发现的作品。
这是使用来自Stream
的原始PDF,并将合并的输出生成为另一个Stream
,但您应该能够根据自己的需要进行调整。
var originalPdfStream = GetOriginalPdfStream();
var pdfDocument = Document();
var finalPdfStream = new MemoryStream();
var pdfWriter = PdfWriter.GetInstance(pdfDocument, finalPdfStream);
pdfDocument.Open();
// Add the originalPdfStream into the pdfDocument
var originalPdfReader = new PdfReader(originalPdfStream);
AddPdf(document, writer, reader);
// Code to add other items to the pdfDocument.
pdfWriter.CloseStream = false;
pdfDocument.Close();
finalPdfStream.Position = 0;
return finalPdfStream;
然后,以下方法将您的文档和编写者以及读者添加到要添加的文档中。
/// <summary>
/// Merge a PDF file into a PDF document.
/// </summary>
/// <param name="document">The PDF document.</param>
/// <param name="writer">The PDF writer.</param>
/// <param name="reader">A PDF reader.</param>
private static void AddPdf(Document document, PdfWriter writer, PdfReader reader)
{
if (document == null) throw new ArgumentNullException("document");
if (writer == null) throw new ArgumentNullException("writer");
if (reader == null) throw new ArgumentNullException("reader");
var numberOfPages = reader.NumberOfPages;
var originalPageSize = document.PageSize;
// Iterate through all pages
for (var currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)
{
// Determine page size for the current page
document.SetPageSize(reader.GetPageSizeWithRotation(currentPageIndex));
// Create page
document.NewPage();
var importedPage = writer.GetImportedPage(reader, currentPageIndex);
// Determine page orientation and add page.
var pageRotation = reader.GetPageRotation(currentPageIndex);
var pageWidth = reader.GetPageSizeWithRotation(currentPageIndex).Width;
var pageHeight = reader.GetPageSizeWithRotation(currentPageIndex).Height;
switch (pageRotation)
{
case 0:
writer.DirectContent.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
break;
case 90:
writer.DirectContent.AddTemplate(importedPage, 0, -1f, 1f, 0, 0, pageHeight);
break;
case 180:
writer.DirectContent.AddTemplate(
importedPage, -1f, 0, 0, -1f, pageWidth, pageHeight);
break;
case 270:
writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageWidth, 0);
break;
default:
throw new Exception("Unexpected page rotation: [{0}].", pageRotation);
}
}
document.SetPageSize(originalPageSize);
}
答案 1 :(得分:3)
只要添加的内容仅在新页面上(如示例代码所示),您可以创建添加内容,就好像创建一个新的中间PDF(如果不是太大,它可以驻留在内存中)和然后使用PdfCopy
:
using (MemoryStream ms = new MemoryStream()) {
// step 1
using (Document document = new Document()) {
// step 2
using (PdfCopy copy = new PdfCopy(document, ms)) {
// step 3
document.Open();
// step 4
for (int i = 0; i < pdf.Count; ++i) {
PdfReader reader = ...;// retrieve a PdfReader for the i'th PDF to concatenate
// loop over the pages in that document
int n = reader.NumberOfPages;
for (int page = 0; page < n; ) {
copy.AddPage(copy.GetImportedPage(reader, ++page));
}
}
}
}
byte[] data = ms.ToArray();
...
}
(从Webified iTextSharp Example Concatenate.cs无耻地复制)
另一方面,如果您想在现有页面上标记某些内容,则更有可能需要PdfStamper
:
PdfReader reader = new PdfReader(resource);
using (var ms = new MemoryStream()) {
using (PdfStamper stamper = new PdfStamper(reader, ms)) {
PdfContentByte canvas = stamper.GetOverContent(1);
ColumnText.ShowTextAligned(
canvas,
Element.ALIGN_LEFT,
new Phrase("Hello people!"),
36, 540, 0
);
}
byte[] data = ms.ToArray();
...
}
(还从Webified iTextSharp Example StampText.cs无耻地复制)
有关其他背景信息,请阅读chapter 6的免费样本iText in Action — 2nd Edition。