iTextSharp(C#):在位置处添加文本(覆盖所有内容)

iTextSharp(C#):在位置处添加文本(覆盖所有内容),c#,wpf,text,itextsharp,positioning,C#,Wpf,Text,Itextsharp,Positioning,我试图在WPF项目中使用iTextSharp,在给定的点上,将文本添加到现有PDF中,而不是其他任何内容。基本上是在纸质文档上书写的数字等价物 我尝试了多种方法,但似乎没有任何东西能够将文本写入新的PDF。我的代码在测试各种东西时很混乱(留下来让我知道我尝试了什么-是的,我将在解析后清除它),所以我将尝试获取所有重要的行 var stream = new FileStream(targetFilePath, FileMode.Create); var doc = new iTextSharp.t

我试图在WPF项目中使用iTextSharp,在给定的点上,将文本添加到现有PDF中,而不是其他任何内容。基本上是在纸质文档上书写的数字等价物

我尝试了多种方法,但似乎没有任何东西能够将文本写入新的PDF。我的代码在测试各种东西时很混乱(留下来让我知道我尝试了什么-是的,我将在解析后清除它),所以我将尝试获取所有重要的行

var stream = new FileStream(targetFilePath, FileMode.Create);
var doc = new iTextSharp.text.Document();
var target = new PdfCopy(doc, stream);

doc.Open();

var baseFont = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);

foreach (var vm in Pages) // Cycles through pages in WPF object...
{
    var srcDoc = vm.DocTmpFName;

    if (Path.GetExtension(srcDoc).ToUpperInvariant() == ".PDF")
    {
        var reader = new iTextSharp.text.pdf.PdfReader(srcDoc);
        var page = reader.GetPageN(vm.Number);
        var stamper = new PdfStamper(reader, stream);

        target.AddPage(target.GetImportedPage(reader, vm.Number));

        page.Put(PdfName.ROTATE, new PdfNumber(vm.Rotation % 360f));

        // Inside this 'foreach' loop is what isn't working.  The rest works fine.
        foreach(var str in vm.Strings) // str is a container class (just a string and two 'double' vars for positioning)
        {
            // This isn't writing to new PDF even though it gets run (verified with breakpoints)
            var contentByte = stamper.GetOverContent(vm.Number);

            contentByte.BeginText();
            contentByte.SetTextMatrix((float)str.X, (float)str.Y);
            contentByte.SetFontAndSize(baseFont, 72f); //Making it stupid-big so I don't miss it
            contentByte.ShowText(str.String);
            contentByte.EndText();
        }

        target.FreeReader(reader);
        reader.Close();

    }
}

target.Close();
doc.Close();
stream.Close();
如果你觉得我错过了什么,请告诉我。我试图保持问题区域的上下文,所以希望这不是太可怕的黑客工作

-编辑以更正代码-


编辑

我重命名了一些变量,以便于识别它们的用途。此外,我还添加了新的固定(尽管有缺陷)代码,用于在某个位置添加文本-供以后遇到此问题的任何人使用。=)

@mkl回答后的工作代码:
您不能在
foreach
循环中关闭读卡器。(我怀疑)你也不应该打
target.FreeReader
电话:

foreach(var str in vm.Strings) // str is a container class (just a string and two 'double' vars for positioning)
{
    // This isn't writing to new PDF even though it gets run (verified with breakpoints)
    var contentByte = stamper.GetOverContent(vm.Number);

    contentByte.BeginText();
    contentByte.SetTextMatrix((float)str.X, (float)str.Y);
    contentByte.SetFontAndSize(baseFont, 72f); //Making it stupid-big so I don't miss it
    contentByte.ShowText(str.String);
    contentByte.EndText();
}
//moved the next two lines out of the foreach loop
target.FreeReader(reader);
reader.Close();
这三条线的应用程序相同:

target.Close();
doc.Close();
stream.Close();

它们也应该移出当前包含它们的
foreach(页面中的var vm)
循环。

您不能在
foreach
循环中关闭读卡器。(我怀疑)你也不应该打
target.FreeReader
电话:

foreach(var str in vm.Strings) // str is a container class (just a string and two 'double' vars for positioning)
{
    // This isn't writing to new PDF even though it gets run (verified with breakpoints)
    var contentByte = stamper.GetOverContent(vm.Number);

    contentByte.BeginText();
    contentByte.SetTextMatrix((float)str.X, (float)str.Y);
    contentByte.SetFontAndSize(baseFont, 72f); //Making it stupid-big so I don't miss it
    contentByte.ShowText(str.String);
    contentByte.EndText();
}
//moved the next two lines out of the foreach loop
target.FreeReader(reader);
reader.Close();
这三条线的应用程序相同:

target.Close();
doc.Close();
stream.Close();
它们也应该从当前包含它们的
foreach(页面中的var-vm)
循环中移出。

您的代码有许多问题,其中一些问题@bercoder已经在他的回答中解决了

此外,您还有a
PdfCopy
和多个
PdfStamper
实例写入同一个流中。这将导致流输出完全混乱。如果要在复制的页面上盖章,应使用
PdfCopy.PageStamp
,例如:

using (PdfCopy copy = new PdfCopy(document, OUTPUT_STREAM)) {
    document.Open();
    PdfReader reader1 = new PdfReader(r1);
    int n1 = reader1.NumberOfPages;
    PdfImportedPage page;
    PdfCopy.PageStamp stamp;
    for (int i = 0; i < n1; ) {
        page = copy.GetImportedPage(reader1, ++i);
        stamp = copy.CreatePageStamp(page);
        // CHANGE THE PAGE,
        // e.g. by manipulating stamp.GetOverContent()
        ...
        //
        stamp.AlterContents();
        copy.AddPage(page);
    }
}
使用(PdfCopy副本=新PdfCopy(文档、输出流)){
document.Open();
PdfReader reader1=新PdfReader(r1);
int n1=读取器1.NumberOfPages;
PDF导入页面;
PdfCopy.PageStamp;
对于(int i=0;i
(摘自官方iTextSharp示例)

您的代码有许多问题,@Übercoder在其回答中已经解决了其中一些问题

此外,您还有a
PdfCopy
和多个
PdfStamper
实例写入同一个流中。这将导致流输出完全混乱。如果要在复制的页面上盖章,应使用
PdfCopy.PageStamp
,例如:

using (PdfCopy copy = new PdfCopy(document, OUTPUT_STREAM)) {
    document.Open();
    PdfReader reader1 = new PdfReader(r1);
    int n1 = reader1.NumberOfPages;
    PdfImportedPage page;
    PdfCopy.PageStamp stamp;
    for (int i = 0; i < n1; ) {
        page = copy.GetImportedPage(reader1, ++i);
        stamp = copy.CreatePageStamp(page);
        // CHANGE THE PAGE,
        // e.g. by manipulating stamp.GetOverContent()
        ...
        //
        stamp.AlterContents();
        copy.AddPage(page);
    }
}
使用(PdfCopy副本=新PdfCopy(文档、输出流)){
document.Open();
PdfReader reader1=新PdfReader(r1);
int n1=读取器1.NumberOfPages;
PDF导入页面;
PdfCopy.PageStamp;
对于(int i=0;i

(摘自官方iTextSharp样本)

你说得对。我抄台词的时候一定把它弄糟了。我会更正我的帖子,你说得对。我抄台词的时候一定把它弄糟了。我会更正我的帖子。今天晚些时候我会试试。这可能是从多个源PDF复制页面,这就是我有多个母版的原因。“copy.CratePageStamp”是否不创建新实例?@CheeseMo“copy.CratePageStamp”是否不创建新实例-
PdfCopy.CreatePageStamp
创建新的
PageStamp
。但是
PageStamp
不是一个独立的
PdfStamper
,而是一个复制过程中内置了类似功能的对象。就是这样!谢谢你的参考链接。我编辑了我的帖子,加入了工作代码——详细阐述了你的答案。今天晚些时候我会尝试一下。这可能是从多个源PDF复制页面,这就是我有多个母版的原因。“copy.CratePageStamp”是否不创建新实例?@CheeseMo“copy.CratePageStamp”是否不创建新实例-
PdfCopy.CreatePageStamp
创建新的
PageStamp
。但是
PageStamp
不是一个独立的
PdfStamper
,而是一个复制过程中内置了类似功能的对象。就是这样!谢谢你的参考链接。我编辑了我的帖子,加入了工作代码——详细阐述了你的答案。