使用ITextSharp绘制PDF,无需创建新的PDF

时间:2015-05-27 08:48:56

标签: c# pdf itextsharp

我尝试使用ITextSharp在现有PDF上绘制简单的形状(矩形,圆形......),而不必创建新的PDF。我找到一篇帖子谈论这个问题(itextsharp modify existing pdf (no new source pdf) and add watermark),我想知道是否有人可以告诉我更多相关信息。

我的目标是通过在其上添加一个圆圈来修改pdf,当前的解决方案涉及创建一个新的PDF(Itextsharp)。是否可以在PDF上添加圆圈而无需创建新圆圈? 谢谢。

学家

3 个答案:

答案 0 :(得分: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?

<强>更新

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
  • 也是如此
  • 圆圈的坐标是硬编码的。我使用页面大小来确保它们是相对于坐标系的原点制作的,但可以肯定的是,您可能还想检查是否有裁剪框。

答案 1 :(得分: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); 
} 

答案 2 :(得分:-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();