2015-05-27 7 views
2

Я пытаюсь нарисовать простые формы (прямоугольники, круги ...) в существующем PDF-формате с использованием ITextSharp, не создавая новый PDF-файл. Я нашел сообщение, которое говорит об этой проблеме (itextsharp modify existing pdf (no new source pdf) and add watermark), и я хотел бы знать, сможет ли кто-нибудь рассказать мне об этом подробнее.Опираясь на PDF, используя ITextSharp, не создавая новый PDF-файл

Моя цель - изменить pdf, добавив в него круг, текущее решение связано с созданием нового PDF (Itextsharp). Можно ли добавить круг в PDF без создания нового? Спасибо.

J.

+1

Вы должны указать свой точный вопрос, прежде чем ваш вопрос закрывается как «слишком широким». – vib

+0

Я хочу изменить pdf, добавив в него круг, текущее решение связано с созданием нового PDF (Itextsharp). Можно ли добавить круг в PDF без создания нового? – Json

+0

Редактировать свой вопрос, чтобы уточнить его, и лучше также добавить несколько строк кода, который вы пробовали ..! – TaW

ответ

3

Вы не можете прочитать файл и записать в него одновременно. Подумайте, как работает Word: вы не можете открыть документ Word и написать прямо на него. Word всегда создает временный файл, записывает изменения в него, затем заменяет исходный файл и затем удаляет временный файл.

Вы можете сделать это:

  • читать исходный файл с PdfReader,
  • создать временный файл для PdfStamper, и когда вы закончите,
  • заменить исходный файл с временным файл.

Или:

  • читать исходный файл в byte[],
  • создать PdfReader с этим byte[] и
  • использовать путь к исходному файлу для PdfStamper.

Этот второй вариант более опасен, поскольку вы потеряете исходный файл, если вы делаете что-то, что вызывает исключение в PdfStamper.

Что касается добавления контента с помощью PdfStamper, ознакомьтесь с разделом «Управление существующими PDF-файлами» в бесплатной электронной книге The Best iText Questions on StackOverflow. Вы найдете такие вопросы, как:

Все эти примеры добавить содержимое, создавая PdfContentByte экземпляр так:

PdfContentByte canvas = stamper.getOverContent(pagenumber); 

Это canvas, которую вы должны использовать при рисовании круга на странице с номером страницы pagenumber. Важно, чтобы вы использовали правильные координаты, когда вы это делаете.Вот объясняется здесь: How to position text relative to page using iText?

Update:

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
  • координаты окружности были жестко закодированы. Я использовал размер страницы, чтобы убедиться, что они сделаны относительно происхождения системы координат, хотя, конечно, вы также можете проверить, есть ли Crop Box.
+0

thx для вашего быстрого ответа, мне все еще нужны объяснения, чтобы добавить круг в pdfStamper, мне нужен «PdfContentByte» и «PdfWriter» нет? Кроме того, я не вижу четко, как заменить исходный файл временным файлом: /, thx снова! – Json

+0

Нет, вам не нужен 'PdfWriter'. Ответ, предоставленный @shajeer, совершенно неверен. 'PdfStamper' имеет метод' getOverContent() '. Существует множество примеров. Я приведу несколько примеров. –

+0

ладно, я понимаю =) THX вы очень много. – Json

-1
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(); 
+1

Этот ответ неверен. Предположим, что исходный файл содержит аннотации, форму, закладки, ... затем с помощью 'Document' и' PdfWriter' ** выкинет весь этот контент! ** Если вы хотите штамповать новый контент в документе, вы должны использовать 'PdfStamper'! Также: это не отвечает на вопрос. Вопрос спрашивает. ** Как я могу избежать создания нового файла? ** Вы создаете файл, который заканчивается на 'NEW.pdf', чего пытается избежать OP! –

+0

благодарю за ответ shajeer, но это решение создало новый PDF-документ под названием «Новый», что я хотел бы сделать, это нарисовать оригинальный. – Json

0

Вы МОЖЕТЕ прочитать файл и написать ему одновременно.

Вот пример:

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); 
} 
+0

Используя 'Stream' вместо имени файла в качестве аргумента конструктора' PdfReader', вы фактически делаете iText считываемым потоком в массив байтов перед построением 'PdfReader'. Таким образом, ваш код по существу является реализацией второго варианта в ответе @ Bruno: * прочитайте исходный файл в 'byte []', создайте 'PdfReader' с этим' byte [] 'и используйте путь к исходному файлу для 'PdfStamper'. * – mkl

+0

Одна коррекция: вы используете' FileMode.Open' для аргумента 'FileStream' конструктора' PdfWriter'. Это плохая идея, так как это заставляет вас записывать в существующий файл, а если новый файл короче исходного, конечная часть старого файла остается, и вы фактически получаете разбитый PDF-файл. Вместо этого вы должны использовать 'FileMode.Create' или' FileMode.Truncate'. – mkl

+0

Спасибо! Я новичок, извините: D –

Смежные вопросы