因此,我已使该函数返回了代表对象的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)
重新导入它们。
答案 0 :(得分:0)
此处的“问题”:您从以“导入”模式打开的PDF文档中导入页面,并将其添加到临时PDF文档中。然后循环浏览此临时文档的页面,然后尝试将它们添加到最终文档中,这将导致错误消息。
一种简单的解决方法是将临时PDF文档保存到MemoryStream
,然后在导入模式下从该流中打开新的PDF文档,从而允许将页面添加到新的PDF文档中。
恕我直言,消除临时PDF并将导入的PDF页面直接添加到目标PDF将是一个更干净的解决方案。只需将最后一个PdfDocument
作为参数传递给GetPdfPages
,并让该方法将页面直接添加到最终目标,这是一个简单的更改。