Рисование на PDF с помощью ITextSharp, без создания нового PDF
Я пытаюсь рисовать простые фигуры (прямоугольники, круги..) на существующий PDF с помощью ITextSharp, без необходимости создавать новый PDF. Я нашел сообщение, которое говорит об этой проблеме ( itextsharp изменить существующий pdf (нет нового исходного pdf) и добавить водяной знак), и я хотел бы знать, может ли кто-нибудь рассказать мне больше об этом.
Моя цель состоит в том, чтобы изменить pdf, добавив круг на нем, текущее решение включает в себя создание нового PDF (Itextsharp). Можно ли добавить круг на PDF-файл без создания нового ?
Спасибо.
J.
3 ответов:
Вы не можете одновременно читать файл и писать в него. Подумайте о том, как работает Word: вы не можете открыть документ Word и написать прямо в него. Word всегда создает временный файл, записывает в него изменения, затем заменяет им исходный файл, а затем выбрасывает временный файл.
Это тоже можно сделать:
- прочитайте исходный файл с помощью
PdfReader,- создайте временный файл для
PdfStamper, а когда закончите,- замените исходный файл на временный файл.
Или:
- считайте исходный файл в
byte[],- создайте
PdfReaderс помощью этогоbyte[]и- используйте путь к исходному файлу для
PdfStamper.Этот второй вариант более опасен, так как вы потеряете исходный файл, если сделаете что-то, что вызовет исключение в
PdfStamper.Что касается добавления контента с помощью
PdfStamper, пожалуйста, взгляните на раздел, озаглавленный "манипулирование существующими PDF-файлами" в бесплатной электронной книге The Best iText Вопросы по StackOverflow . Вы найдете такие вопросы, как:
- Как добавить водяной знак в PDF-файл?
- Как вставить гиперссылку на другую страницу с iTextSharp в существующий PDF-файл?
- iText-как наложить печать изображения на существующий PDF и создать якорь
- ...
Все эти примеры добавляют контент, создавая экземпляр
PdfContentByteследующим образом:PdfContentByte canvas = stamper.getOverContent(pagenumber);Именно это
canvasВам и нужно использовать при рисовании круга на странице с номером страницыpagenumber. Важно, чтобы при этом вы использовали правильные координаты. Это объясняется здесь: Как расположить текст относительно страницы с помощью iText?Обновление:
Json опубликовал в комментариях следующий код:
string oldFile = @"C:\Users\ae40394\Desktop\hello.pdf"; string newFile = @"C:\Users\ae40394\Desktop\NEW.pdf"; // creating a reader with the original PDF PdfReader reader = new PdfReader(oldFile); Rectangle rect = reader.GetPageSize(1); FileStream fs = new FileStream(newFile,FileMode.Create); using (PdfStamper stamper = new PdfStamper(reader, fs)) { // modify the pdf content PdfContentByte cb = stamper.GetOverContent(1); cb.SetColorStroke(iTextSharp.text.BaseColor.GREEN); cb.SetLineWidth(5f); cb.Circle(rect.GetLeft() + 30, rect.GetBottom() + 30 ,20f); cb.Stroke(); } reader.Close(); File.Replace(@"C:\Users\ae40394\Desktop\NEW.pdf", @"C:\Users\ae40394\Desktop\hello.pdf", @"C:\Users\ae40394\Desktop\hello.pdf.bac");Я немного адаптировал код, потому что:
- Нет необходимости в объекте
Document,stamperзакрывается, когдаusingзакрыто,- Когда
Координаты круга были жестко закодированы. Я использовал размер страницы, чтобы убедиться, что они сделаны относительно начала координат, хотя, чтобы быть уверенным,вы также можете проверить, есть ли поле обрезки.stamperзакрыт, то иFileStream
Вы можете одновременно читать файл и записывать в него данные.
Вот пример:
private void button4_Click(object sender, EventArgs e) { using (PdfReader pdfReader = new PdfReader(new FileStream(pdfInput, FileMode.Open, FileAccess.Read, FileShare.Read))) { using (PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(pdfInput, FileMode.Open, FileAccess.Write, FileShare.None))) { PdfContentByte canvas = pdfStamper.GetUnderContent(1); canvas.SetColorFill(BaseColor.YELLOW); canvas.Rectangle(36, 786, 66, 16); canvas.Fill(); } } // PDF Datei im Anschluss anzeigen/öffnen System.Diagnostics.Process.Start(pdfInput); }
string oldFile = @"C:\...6166-21.pdf"; string newFile = @"C:\...NEW.pdf"; // open the reader PdfReader reader = new PdfReader(oldFile); Rectangle size = reader.GetPageSizeWithRotation(1); Document document = new Document(size); FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write); PdfWriter writer = PdfWriter.GetInstance(document, fs); document.Open(); // the pdf content PdfContentByte cb = writer.DirectContent; cb.SetColorStroke(iTextSharp.text.BaseColor.GREEN); cb.Circle(150f, 150f, 50f); cb.Stroke(); // create the new page and add it to the pdf PdfImportedPage page = writer.GetImportedPage(reader, 1); cb.AddTemplate(page, 0, 0); // close the streams and voilá the file should be changed :) document.Close(); fs.Close(); writer.Close(); reader.Close();
Comments