Добавить элементы в существующий PDF с iTextSharp
Является ли правильный способ добавить элементы в существующий 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());
2 ответа
Вот как я это делал в прошлом. Вам необходимо использовать новый поток для средства записи PDF и добавить исходное содержимое PDF в новый документ. Это может быть не самый лучший или самый эффективный способ выполнения этого, это просто то, что я нашел работы.
Это работает с моим оригинальным PDF из Stream
и создание объединенного выхода в качестве другого 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);
}
Пока добавленный контент должен быть только на новых страницах (как показывает пример кода), вы можете создавать дополнения, как будто создаете новый промежуточный PDF (если он не слишком большой, он может находиться в памяти), а затем объединять 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();
...
}
(Бесстыдно скопировано из примера Webaten iTextSharp 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();
...
}
(Также бесстыдно скопировано из примера StampText.cs Webified iTextSharp)
Для получения дополнительной справочной информации прочитайте бесплатный пример главы 6 iText в действии - 2-е издание.