使用iTextSharp将多个页面添加到pdf表单

时间:2015-02-03 16:54:37

标签: c# itextsharp memorystream

我正在尝试填写pdf表单,表单可能有多个相同表单的页面,因此我不想将每个页面写入磁盘,而是想在内存中创建一个包含所有页面的pdf文档。

我已经看到很多关于使用FileStream添加现有pdf文件的网页的示例,但没有真正用于填充论坛并将其添加到MemoryStream

基本上我需要用PdfStamper填写论坛,然后将该表单附加到“主”MemoryStream,因为我不想将其写入文件。

这基本上是我到目前为止所拥有的

List<Person> people = arson.getPeople();
MemoryStream main = new MemoryStream();
foreach (Person person in people )
{
    PdfReader reader = new PdfReader(pathToPdf);
    MemoryStream mem = new MemoryStream();
    PdfStamper stamper = new PdfStamper(reader, mem);

    //fill in forum with data from person then append

}

填写表单不是问题,它只是将新页面添加到main流,以便它们都在同一文档中。如何在内存中添加多个页面而不是先将其写入磁盘?

1 个答案:

答案 0 :(得分:3)

您是否观看过iText视频教程?您可以找到它here,并且有一个示例正在执行完全您要求的内容。

如果您不喜欢观看视频,也可以咨询chapter 6 of my book。你也会找到一个解释该怎么做的例子。

如果您偏好“食谱书”风格,请查看The Best iText Questions on StackOverflow。它至少有一个涉及PdfStamperMemoryStream组合的示例。

如果您确实阅读了文档,那么您将找到示例DataSheets2

// step 1
using (Document document = new Document()) {
    // step 2
    using (PdfSmartCopy copy = new PdfSmartCopy(document, ms)) {
        // step 3
        document.Open();
        // step 4
        AddDataSheets(copy);
    }
 }

您可以在DataSheets1中了解第4步的内容,了解第4步的内容:

public void AddDataSheets(PdfCopy copy) {
    IEnumerable<Movie> movies = PojoFactory.GetMovies();
    // Loop over all the movies and fill out the data sheet
    foreach (Movie movie in movies) {
        PdfReader reader = new PdfReader(DATASHEET_PATH);
        using (var ms = new MemoryStream()) {
            using (PdfStamper stamper = new PdfStamper(reader, ms)) {
            Fill(stamper.AcroFields, movie);
            stamper.FormFlattening = true;
        }
        reader = new PdfReader(ms.ToArray());
        copy.AddPage(copy.GetImportedPage(reader, 1));
    }
}

正如您所看到的,DATASHEET_PATH是表单的路径,我们将一遍又一遍地重复使用。我们使用PdfStamper在内存中填写表单。我们使用PdfReader作为参数创建了一个新的ms.ToArray()实例。

在这种情况下,我们只将第1页添加到新PDF中。如果有更多页面,则需要遍历不同的页面。

您可能希望将DataSheets1生成的结果与DataSheets2生成的结果进行比较。您会注意到DataSheets1的示例。

您已经知道FillDataSheet()方法的含义。如果没有,请查看FillDataSheet示例:

public static void Fill(AcroFields form, Movie movie) {
    form.SetField("title", movie.MovieTitle);
    form.SetField("director", GetDirectors(movie));
    form.SetField("year", movie.Year.ToString());
    form.SetField("duration", movie.Duration.ToString());
    form.SetField("category", movie.entry.category.Keyword);
    foreach (Screening screening in movie.entry.Screenings) {
        form.SetField(screening.Location.Replace('.', '_'), "Yes");
    }
}