PDFsharp-导入PdfDocument对象;串联页面

时间:2018-07-17 11:39:56

标签: c# pdfsharp

因此,我已使该函数返回了代表对象的PdfPage。我需要一个功能来从具有该功能的多个对象中调用该功能,并将其全部组合成PdfDocument

功能如下:

public List<PdfPage> GetPdfPages(DateTime date) {
    PdfDocument pdf = new PdfDocument();

    if (!File.Exists(Path.Combine(Commons.PATH, "template.pdf")))
        throw new FileNotFoundException("Template not found");

    PdfDocument template = PdfReader.Open(Path.Combine(Commons.PATH, "template.pdf"), PdfDocumentOpenMode.Import);

    if (template.Pages.Count < 2)
        throw new FileLoadException("Template corrupted");

    for (int i = 0; i < template.PageCount; i++) pdf.AddPage(template.Pages[i]);

    XFont main = new XFont("Open Sans Light", 10, XFontStyle.Regular);
    XBrush brush = XBrushes.Black;

    foreach (PdfPage page in pdf.Pages) {

        XGraphics graph = XGraphics.FromPdfPage(page);

        if (employee != null && employee.name != null) graph.DrawString(employee.name, main, brush, 58.5f, 93f);
        graph.DrawString(date.ToString("d MMMM yyyy", new CultureInfo("id")), main, brush, 58.5f, 78.25f);

        graph.DrawString(GetTotalDaysWorked().ToString(), main, brush, 134.65f, 113.5f);

        if (employee != null && GetPremi()) graph.DrawString(employee.premi.ToString("C", new CultureInfo("id")), main, brush, 211.25f, 113.5f);
        if (employee != null) graph.DrawString(GetPokok().ToString("C", new CultureInfo("id")), main, brush, 211.25f, 127.5f);

        for (int i = 0; i < days.Length; i++) {
            Day day = days[i];

            graph.DrawString(day.check_in.ToString("H.mm", new CultureInfo("id")), main, brush, 59.5f, 148.82f + (i * 14.173f));
            graph.DrawString(day.check_out.ToString("H.mm", new CultureInfo("id")), main, brush, 95.75f, 148.82f + (i * 14.173f));
            graph.DrawString(day.GetWorkDuration().ToString(new CultureInfo("id")), main, brush, 135.65f, 148.82f + (i * 14.173f));
        }

        graph.DrawString(prev_over.ToString(new CultureInfo("id")), main, brush, 135.65f, 248f);

        graph.DrawString(GetTotalHoursWorked().ToString(new CultureInfo("id")), main, brush, 135.65f, 264.85f);

        if (employee != null) graph.DrawString((GetTotalHoursWorked() * employee.wage).ToString("C", new CultureInfo("id")), main, brush, 211.25f, 264.85f);

        graph.DrawString(GetLunchCoefficient().ToString(new CultureInfo("id")), main, brush, 135.645f, 281.546f);

        graph.DrawString((GetLunchCoefficient() * Commons.CurrentConfig.lunch_money).ToString("C", new CultureInfo("id")), main, brush, 211.25f, 281.5f);

        graph.DrawString(bpjs_tk.ToString("C", new CultureInfo("id")), main, brush, 211.2415f, 319f);
        graph.DrawString(bpjs_kes.ToString("C", new CultureInfo("id")), main, brush, 211.2415f, 333.175f);
        graph.DrawString(debts.ToString("C", new CultureInfo("id")), main, brush, 211.2415f, 347.35f);
        graph.DrawString(deposits.ToString("C", new CultureInfo("id")), main, brush, 211.2415f, 361.5f);

        graph.DrawString(others_desc, main, brush, 88.77f, 375.7f);
        graph.DrawString(others_amt.ToString("C", new CultureInfo("id")), main, brush, 211.25f, 375.7f);

        graph.DrawString(GetTotalEarnings().ToString("C", new CultureInfo("id")), main, brush, 211.25f, 389.85f);

        graph.DrawString((employee.balance - debts + deposits).ToString("C", new CultureInfo("id")), main, brush, 125.75f, 404f);
    }

    List<PdfPage> list = new List<PdfPage>();
    foreach (PdfPage p in pdf.Pages) list.Add(p);

    return list;
}

它所做的只是在模板上绘制数据并返回页面。

以下是调用所有GetPdfPages()的函数:

private void printAllToolStripMenuItem_Click(object sender, EventArgs e) {
        SaveFileDialog dialog = new SaveFileDialog() { Filter = "PDF Document (*.pdf)|*.pdf|All files (*.*)|*.*", FileName = "Print.pdf" };
        if (dialog.ShowDialog() != DialogResult.OK) return;

        PdfDocument pdf = new PdfDocument();

        foreach(Slip slip in Commons.CurrentBatch.slips) {
            try {
                List<PdfPage> doc = slip.GetPdfPages(Commons.CurrentBatch.date);
                foreach (PdfPage page in doc) pdf.AddPage(page);
            } catch (FileNotFoundException x) {
                MessageBox.Show("The Template is missing. Please reinstall using the installer", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Debug.WriteLine(x.Message);
                return;
            } catch (FileLoadException x) {
                MessageBox.Show("The Template is corrupted. Please reinstall using the installer", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Debug.WriteLine(x.Message);
                return;
            }
        }

        pdf.Save(Path.GetFullPath(dialog.FileName));
    }

但是,使用此方法将抛出此异常:

System.InvalidOperationException: A PDF document must be opened with PdfDocumentOpenMode.Import to import pages from it.
   at PdfSharp.Pdf.PdfPages.ImportExternalPage(PdfPage importPage)
   at PdfSharp.Pdf.PdfPages.Insert(Int32 index, PdfPage page)
   at PdfSharp.Pdf.PdfDocument.AddPage(PdfPage page)
   at Project.FormEditor.PrintBtn_Click(Object sender, EventArgs e) in Project\FormEditor.cs:line 352

注意:有问题的代码行是pdf.AddPage(page);

是否可以重新导入这些页面,以便可以将其添加到PdfDocument中?

我不想使用的另一种方法,但是如果需要的话,我会将GetPdfPages()的所有结果保存到文件中,然后使用PdfReader.Open(path, PdfDocumentOpenMode.Import)重新导入它们。

1 个答案:

答案 0 :(得分:0)

此处的“问题”:您从以“导入”模式打开的PDF文档中导入页面,并将其添加到临时PDF文档中。然后循环浏览此临时文档的页面,然后尝试将它们添加到最终文档中,这将导致错误消息。

一种简单的解决方法是将临时PDF文档保存到MemoryStream,然后在导入模式下从该流中打开新的PDF文档,从而允许将页面添加到新的PDF文档中。

恕我直言,消除临时PDF并将导入的PDF页面直接添加到目标PDF将是一个更干净的解决方案。只需将最后一个PdfDocument作为参数传递给GetPdfPages,并让该方法将页面直接添加到最终目标,这是一个简单的更改。