关于c#:动态生成的pdf添加第二页

Add second page to the dynamically generated pdf

我有一个场景,我需要根据他们加入的课程为学生生成证书。如果学生加入单个课程,则颁发单个证书,如果学生加入多个课程,则单个 pdf 多页(每个页面将有每个课程的单独证书)需要生成。

以下代码帮助我为单个课程生成 pdf。如何为多个课程生成 pdf。如果有多个课程,则下一页也应使用放置在 path:

的相同模板

Server.MapPath("~/Template/CertificateTemplate.pdf");

我正在使用 itextsharp 库来创建文档。下面是用来生成pdf的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 string formFile = Server.MapPath("~/Template/CertificateTemplate.pdf")                                        
 string newFile = Server.MapPath("~/Certificates/" + _dbRegistration.RegistrationNumber +".pdf");

 PdfReader reader = new PdfReader(formFile);
 PdfStamper stamper = new PdfStamper(reader, new FileStream(
                        newFile, FileMode.Create));

 var pdfContentBuffer = stamper.GetOverContent(1);

 AcroFields fields = stamper.AcroFields;
 fields.SetField("ID", _dbRegistration.RegistrationNumber);
 fields.SetField("Course", _dbRegistration.Course.FirstOrDefault().Name);
 ...
 stamper.FormFlattening = true;
 stamper.Close();

我想在以下条件下附加 pdf

1
2
3
4
5
6
7
for(int i=0;i<course.count;i++)
{
     AcroFields fields = stamper.AcroFields;
     fields.SetField("ID", _dbRegistration.RegistrationNumber);
     fields.SetField("Course",   _dbRegistration.Course[i].Name);
     ...
}

请允许我更新您的代码。阅读作为评论添加的部分,了解有关我所做更改的更多信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
string formFile = Server.MapPath("~/Template/CertificateTemplate.pdf")                                        
string newFile = Server.MapPath("~/Certificates/"
_dbRegistration.RegistrationNumber +".pdf");

PdfReader reader = new PdfReader(formFile);
PdfStamper stamper = new PdfStamper(reader, new FileStream(
                        newFile, FileMode.Create));

// You don't need this function here!
// var pdfContentBuffer = stamper.GetOverContent(1);

AcroFields fields = stamper.AcroFields;
fields.SetField("ID", _dbRegistration.RegistrationNumber);
...
...
stamper.FormFlattening = true;

// You can't reuse a PdfReader object when you're using PdfStamper,
// so let's create a new instance:
PdfReader reader2 = new PdfReader(formFile);
// Let's assume that your document only has one page,
// and add a second page that has the same size as the first page:
stamper.InsertPage(2, reader2.GetPageSize(1));
// Now we get the PdfContentByte of that second page:
var cb = stamper.GetOverContent(2);
// And we add the content of the first page at position 0, 0
cb.AddTemplate(stamper.GetImportedPage(reader2, 1), 0, 0);

stamper.Close();
// Don't forget to close the PdfReader instances!
reader.Close();
reader2.Close();

现在您将拥有一个 PDF,其中第一页包含添加了字段的模板;第二页将是没有字段的相同模板,这正是您正在寻找的内容(在您问题的版本 1 中)。

更新:

在您的问题的第二个版本中,您现在说您要创建一个由多个页面组成的 PDF,其中使用不同的字段数据集重复相同的表单。

以下视频教程详细解释了如何执行此操作:https://www.youtube.com/watch?v=6YwDME0Fl1c

可以在此处找到本教程的示例:使用表格进行报告。如果您浏览这些示例,您就会明白有不同的方法可以实现这一目标。

首先连接表单,然后填写字段

这不是最优雅的方式,但您可以将表单与自身连接起来,使其有两页。这并不优雅,而且很容易出错。这就是这个问题的解释:http://developers.itextpdf.com/question/how-merge-forms-different-files-one-pdf

第一个障碍是您需要通知 PdfCopy 您正在合并包含表单字段的文档(如果您不这样做,字段会丢失)。第二个障碍是您必须重命名字段,因为与只有一个名称的字段对应的两个小部件注释只能有一个值。

我不建议使用这种方法。

先填充和展平,然后连接

这在我对如何将不同文件中的表单合并到一个 PDF 中的问题的第二部分中进行了解释。这里也有回答:iTextSharp 填写表单和创建多个页面,或者,如果您不了解 Java 代码并且更喜欢 C# 代码:来自预定义模板的多页 PDF 文档


以下函数创建页面并插入更多页面,以便输出pdf的页面为4的倍数

这里使用了itextsharp dll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var tempFileLocation = Path.GetTempFileName();
string sourcePdfPath =" pdf file path here";    
var bytes = File.ReadAllBytes(sourcePdfPath);

using (var reader = new PdfReader(bytes))
{
    var numberofPages = reader.NumberOfPages;
    var modPages = (numberofPages % 4);
    var pages = modPages == 0 ? 0 : 4 - modPages;

    if (pages == 0)
        return;

    using (var fileStream = new FileStream(tempFileLocation, FileMode.Create, FileAccess.Write))
    {
        using (var stamper = new PdfStamper(reader, fileStream))
        {
            var rectangle = reader.GetPageSize(1);
            for (var i = 1; i <= pages; i++)
                stamper.InsertPage(numberofPages + i, rectangle);
        }
    }
}

File.Delete(sourcePdfPath);
File.Move(tempFileLocation, sourcePdfPath);
}