我正在编写一个程序来填写包含36个订单项的PDF订单。有时会有超过36个项目,所以我希望能够在保存之前添加剩余项目的第二页。以下是我目前拥有的填写PDF订单项的代码:
private SaveResult WritePDF(ref ObservableCollection<OrderLineItem> saveObj)
{
try
{
if (saveObj == null) throw new ArgumentNullException("Save Object is null");
var theForm = ReadResource("LineItemOrderForm");
var sfd = new SaveFileDialog
{
AddExtension = true,
InitialDirectory = DesktopPath,
DefaultExt = ".pdf",
RestoreDirectory = true,
Filter = "Adobe PDF Files (.pdf)|*.pdf",
};
var saveResult = sfd.ShowDialog();
if (saveResult == false) return SaveResult.Cancelled;
var outPath = sfd.FileName;
var timesBasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "TIMESBD.TTF");
var timesBaseFont = BaseFont.CreateFont(timesBasePath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
using (var pdfReader = new PdfReader(theForm))
{
var fs = new FileStream(outPath, FileMode.Create);
using (var pdfStamper = new PdfStamper(pdfReader, fs))
{
var form = pdfStamper.AcroFields;
form.AddSubstitutionFont(timesBaseFont);
var i = 1;
form.SetField("OrderFormDealerName", Constants.DealerName);
form.SetFieldProperty("OrderFormDealerName", "textcolor", BaseColor.BLACK, null);
foreach (var item in saveObj)
{
form.SetField($"LineItem{i:D2}", item.LineItemNumber.ToString(CultureInfo.InvariantCulture));
form.SetFieldProperty($"LineItem{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"Qty{i:D2}", item.Quantity.ToString(CultureInfo.InvariantCulture));
form.SetFieldProperty($"Qty{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"PartNumber{i:D2}", item.PartNumber);
form.SetFieldProperty($"PartNumber{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"Hinging{i:D2}", item.Hinging.ToString());
form.SetFieldProperty($"Hinging{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"Finished{i:D2}", item.Finished.ToString());
form.SetFieldProperty($"Finished{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"UnitPrice{i:D2}", $"{item.UnitPrice:C0}");
form.SetFieldProperty($"UnitPrice{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"ModPrice{i:D2}", $"{item.ModifyPrice:C0}");
form.SetFieldProperty($"ModPrice{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"ExtPrice{i:D2}", $"{item.ExtendedPrice:C0}");
form.SetFieldProperty($"ExtPrice{i:D2}", "textcolor", BaseColor.BLACK, null);
i++;
}
pdfStamper.FormFlattening = false;
pdfStamper.Close();
}
pdfReader.Close();
return SaveResult.Success;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "WritePDF()");
return SaveResult.Failure;
}
}
调整此代码以获得我想要的结果的最佳方法是什么?
编辑:我正在使用通过NuGet包管理器安装的iTextSharp版本5.5.11。
答案 0 :(得分:0)
我最终决定制作临时PDF,合并它们,保存合并文件,然后删除临时文件。
以下是我在原始问题中发布的修改方法:
private SaveResult WritePDF(ref List<OrderLineItem> saveObj)
{
try
{
if (saveObj == null) throw new ArgumentNullException("Save Object is null");
var theForm = ReadResource("LineItemOrderForm");
var pageCount = 1.0;
var multiPage = (saveObj.Count > 36);
var multiList = new List<List<OrderLineItem>>();
var fileList = new List<string>();
if (multiPage)
{
var temp = (saveObj.Count / 36.0);
pageCount = Math.Ceiling(temp);
multiList = saveObj.ChunkBy(36);
}
else
{
multiList.Add(saveObj);
}
var sfd = new SaveFileDialog
{
AddExtension = true,
InitialDirectory = DesktopPath,
DefaultExt = ".pdf",
RestoreDirectory = true,
FileName = "Pioneer Order Form",
Filter = "Adobe PDF Files (.pdf)|*.pdf",
};
var saveResult = sfd.ShowDialog();
if (saveResult == false) return SaveResult.Cancelled;
var fileName = sfd.FileName;
var timesBasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "TIMESBD.TTF");
var timesBaseFont = BaseFont.CreateFont(timesBasePath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
var pageNumber = 1;
foreach (var page in multiList)
{
var tempFileName = Path.Combine(BasePath, Extensions.TempPdfName());
fileList.Add(tempFileName);
using (var pdfReader = new PdfReader(theForm))
{
var fs = new FileStream(tempFileName, FileMode.Create);
using (var pdfStamper = new PdfStamper(pdfReader, fs))
{
var form = pdfStamper.AcroFields;
form.AddSubstitutionFont(timesBaseFont);
var i = 1;
form.SetField("OrderFormDealerName", Constants.DealerName);
form.SetFieldProperty("OrderFormDealerName", "textcolor", BaseColor.BLACK, null);
form.SetField("PageNumber", pageNumber);
form.SetField("TotalPages", Convert.ToInt32(pageCount));
foreach (var item in page)
{
form.SetField($"LineItem{i:D2}", item.LineItemNumber);
form.SetFieldProperty($"LineItem{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"Qty{i:D2}", item.Quantity);
form.SetFieldProperty($"Qty{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"PartNumber{i:D2}", item.PartNumber);
form.SetFieldProperty($"PartNumber{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"Hinging{i:D2}", item.Hinging);
form.SetFieldProperty($"Hinging{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"Finished{i:D2}", item.Finished);
form.SetFieldProperty($"Finished{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"UnitPrice{i:D2}", $"{item.UnitPrice:C0}");
form.SetFieldProperty($"UnitPrice{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"ModPrice{i:D2}", $"{item.ModifyPrice:C0}");
form.SetFieldProperty($"ModPrice{i:D2}", "textcolor", BaseColor.BLACK, null);
form.SetField($"ExtPrice{i:D2}", $"{item.ExtendedPrice:C0}");
form.SetFieldProperty($"ExtPrice{i:D2}", "textcolor", BaseColor.BLACK, null);
i++;
}
pdfStamper.FormFlattening = true;
pdfStamper.Close();
}
pdfReader.Close();
}
pageNumber++;
}
var result = MergePDFs(fileList, fileName);
foreach (var file in fileList)
{
File.Delete(file);
}
return result ? SaveResult.Success : SaveResult.Failure;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "WritePdf()");
return SaveResult.Failure;
}
}
我使用了来自another question's answer的解决方案来合并临时PDF:
public static bool MergePDFs(IEnumerable<string> fileNames, string targetPdf)
{
var merged = true;
using (var stream = new FileStream(targetPdf, FileMode.Create))
{
var document = new Document();
var pdf = new PdfCopy(document, stream);
PdfReader reader = null;
try
{
document.Open();
foreach (var file in fileNames)
{
reader = new PdfReader(file);
pdf.AddDocument(reader);
reader.Close();
}
}
catch (Exception)
{
merged = false;
reader?.Close();
}
finally
{
document.Close();
}
}
return merged;
}
我还利用.ChunkBy(int)
扩展程序from here将源列表拆分为N个36个订单项列表:
public static List<List<T>> ChunkBy<T>(this IEnumerable<T> source, int chunkSize)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / chunkSize)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}