我正在使用此脚本循环访问用户文件并填写details.pdf模板的副本,并将它们合并为一个文件。
我遇到的问题是tfTotalPrice字段不计算,直到我手动打开文档javascript并更改某些内容,例如添加警报。我认为这可能与需要一个" / CO"字典键,但我不明白为什么。我刚读过ISO32000-1 doc。
static void Main(string[] args)
{
int i = 0;
int partsTotal = args.Count();
//template page
string tempDetails = @"C:\temp\Details.pdf";
//final multi page quote
string finishedQuote = @"C:\temp\Quote.pdf";
DateTime processedDate = DateTime.Now;
string dateProc = processedDate.ToString("MM/dd/yyyy");
Console.WriteLine("Please Enter Your Customer Name and Press Enter");
string customer = Console.ReadLine();
//This will hold the memory streams and be used to merge them all
List<byte[]> pagesToMerge = new List<byte[]>();
Document doc = new Document();
PdfSmartCopy copy = new PdfSmartCopy(doc, new FileStream(finishedQuote, FileMode.Create));
doc.Open();
copy.SetMergeFields();
copy.SetPdfVersion(PdfWriter.PDF_VERSION_1_7);
List<PdfReader> readers = new List<PdfReader>();
for (i = 0; i < partsTotal; i++)
{
string partFile = args[i].ToString();
string partFileName = partFile.Substring(partFile.LastIndexOf(@"\") + 1);
string partFileLocation = partFile.Substring(0, partFile.LastIndexOf(@"\"));
Console.WriteLine("Processing : " + partFileName);
PdfReader reader = new PdfReader(RenameFields(tempDetails, i));
readers.Add(reader);
copy.AddDocument(reader);
}
doc.Close();
foreach (PdfReader reader in readers)
{
reader.Close();
}
//Should we open it up?
bool response = GetYorN();
if (response == true)
{
System.Diagnostics.Process.Start(finishedQuote);
}
}
static byte[] RenameFields(string src, int i)
{
//This method creates a new document in memory with newly named unique fields
MemoryStream baos = new MemoryStream();
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, baos);
stamper.Writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_7);
stamper.AcroFields.GenerateAppearances = true;
stamper.FormFlattening = false;
AcroFields form = stamper.AcroFields;
//populate names with the dictionary keys for the current file(stream)
string[] names = new string[stamper.AcroFields.Fields.Keys.Count];
stamper.AcroFields.Fields.Keys.CopyTo(names, 0);
//rename all fields in this file(stream)
foreach (string name in names)
{
stamper.AcroFields.RenameField(name, name + i);
}
//Add the calculation action to totalPrice(i)
AcroFields.Item newTotalField = form.GetFieldItem("tfTotalPrice" + i);
PdfDictionary newTotalRefDict = (PdfDictionary)PdfReader.GetPdfObject(newTotalField.GetWidgetRef(0));
PdfString newTotalP = newTotalRefDict.GetAsString(PdfName.T);
AcroFields.Item newSetupField = stamper.AcroFields.GetFieldItem("tfSetupPrice" + i);
PdfDictionary newSetupRefDict = (PdfDictionary)PdfReader.GetPdfObject(newSetupField.GetWidgetRef(0));
PdfString newSetupP = newSetupRefDict.GetAsString(PdfName.T);
AcroFields.Item newToolField = stamper.AcroFields.GetFieldItem("tfToolPrice" + i);
PdfDictionary newToolRefDict = (PdfDictionary)PdfReader.GetPdfObject(newToolField.GetWidgetRef(0));
PdfString newToolP = newToolRefDict.GetAsString(PdfName.T);
AcroFields.Item newPieceField = stamper.AcroFields.GetFieldItem("tfPiecePrice" + i);
PdfDictionary newPieceRefDict = (PdfDictionary)PdfReader.GetPdfObject(newPieceField.GetWidgetRef(0));
PdfString newPieceP = newPieceRefDict.GetAsString(PdfName.T);
AcroFields.Item newFixtureField = stamper.AcroFields.GetFieldItem("tfFixturePrice" + i);
PdfDictionary newFixtureRefDict = (PdfDictionary)PdfReader.GetPdfObject(newFixtureField.GetWidgetRef(0));
PdfString newFixtureP = newFixtureRefDict.GetAsString(PdfName.T);
//Declare the sum action
string newJS = "this.getField(\"" + newTotalP + "\").value = (this.getField(\"" + newPieceP + "\").value + this.getField(\"" + newToolP + "\").value + this.getField(\"" + newFixtureP + "\").value + this.getField(\"" + newSetupP + "\").value);";
PdfAction pdfAction = PdfAction.JavaScript(newJS, stamper.Writer);
PdfDictionary widgetRefDict = (PdfDictionary)PdfReader.GetPdfObject(newTotalField.GetWidgetRef(0));
//AA = Additional Action Annotation Dictionary
PdfDictionary actionDict = widgetRefDict.GetAsDict(PdfName.AA);
//C = Calculation that lives inside of the AA dictionary
PdfDictionary calcDict = actionDict.GetAsDict(new PdfName("C"));
//Plug in the js calc with the new form field names
calcDict.Put(new PdfName("JS"), new PdfString(newJS));
//stamper.SetPageAction(PdfWriter.PAGE_OPEN, PdfAction.JavaScript(newJS, stamper.Writer), 1);
//close up shop and return the new doc in memory
stamper.Close();
reader.Close();
return baos.ToArray();
}
任何帮助将不胜感激,我一直坚持这个:( - 谢谢你
以下是PDFs
的链接答案 0 :(得分:1)
因此,我能够正确计算的唯一方法是用新的字段替换现有字段:
static byte[] RenameFields(string src, int i, string imageName, string customer, string dateProc, string partFileName, string partFileLocation)
{
//This method creates a new document in memory with newly named unique fields
MemoryStream baos = new MemoryStream();
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, baos);
stamper.Writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_7);
stamper.AcroFields.GenerateAppearances = true;
stamper.FormFlattening = false;
AcroFields form = stamper.AcroFields;
//Set Fields that don't need to be recreated
form.SetField("tfCustomer", customer);
form.SetField("tfDate", dateProc);
form.SetField("tfFileName", partFileName);
form.SetField("tfFileLocation", partFileLocation);
form.SetField("tfQuantity", "300");
form.SetField("tfLeadTime", "-");
form.SetField("tfMaterialType", "N/A");
form.SetField("tfThickness", "N/A");
//Place Image
string imageField = "ifPart";
iTextSharp.text.Rectangle imageRect = form.GetFieldPositions(imageField)[0].position;
Bitmap imageBitmap = new Bitmap(imageName);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imageBitmap, System.Drawing.Imaging.ImageFormat.Jpeg);
image.ScaleAbsolute(imageRect.Width, imageRect.Height);
image.SetAbsolutePosition(imageRect.GetLeft(0), imageRect.GetBottom(0));
PdfContentByte content = stamper.GetOverContent(1);
content.AddImage(image);
//populate names with the dictionary keys for the current file(stream)
string[] names = new string[stamper.AcroFields.Fields.Keys.Count];
stamper.AcroFields.Fields.Keys.CopyTo(names, 0);
//rename all fields in this file(stream)
foreach (string name in names)
{
stamper.AcroFields.RenameField(name, name + i);
}
//Add the calculation action to totalPrice(i)
AcroFields.Item newTotalField = form.GetFieldItem("tfTotalPrice" + i);
PdfDictionary newTotalRefDict = (PdfDictionary)PdfReader.GetPdfObject(newTotalField.GetWidgetRef(0));
PdfString newTotalP = newTotalRefDict.GetAsString(PdfName.T);
PdfArray totalRect = newTotalRefDict.GetAsArray(PdfName.RECT);
AcroFields.Item newSetupField = stamper.AcroFields.GetFieldItem("tfSetupPrice" + i);
PdfDictionary newSetupRefDict = (PdfDictionary)PdfReader.GetPdfObject(newSetupField.GetWidgetRef(0));
PdfString newSetupP = newSetupRefDict.GetAsString(PdfName.T);
PdfArray setupRect = newSetupRefDict.GetAsArray(PdfName.RECT);
AcroFields.Item newToolField = stamper.AcroFields.GetFieldItem("tfToolPrice" + i);
PdfDictionary newToolRefDict = (PdfDictionary)PdfReader.GetPdfObject(newToolField.GetWidgetRef(0));
PdfString newToolP = newToolRefDict.GetAsString(PdfName.T);
PdfArray toolRect = newToolRefDict.GetAsArray(PdfName.RECT);
AcroFields.Item newPieceField = stamper.AcroFields.GetFieldItem("tfPiecePrice" + i);
PdfDictionary newPieceRefDict = (PdfDictionary)PdfReader.GetPdfObject(newPieceField.GetWidgetRef(0));
PdfString newPieceP = newPieceRefDict.GetAsString(PdfName.T);
PdfArray pieceRect = newPieceRefDict.GetAsArray(PdfName.RECT);
AcroFields.Item newFixtureField = stamper.AcroFields.GetFieldItem("tfFixturePrice" + i);
PdfDictionary newFixtureRefDict = (PdfDictionary)PdfReader.GetPdfObject(newFixtureField.GetWidgetRef(0));
PdfString newFixtureP = newFixtureRefDict.GetAsString(PdfName.T);
PdfArray fixtureRect = newFixtureRefDict.GetAsArray(PdfName.RECT);
//PiecePrice Field
var llxPiece = Convert.ToDecimal(pieceRect[0].ToString());
var llyPiece = Convert.ToDecimal(pieceRect[1].ToString());
var urxPiece = Convert.ToDecimal(pieceRect[2].ToString());
var uryPiece = Convert.ToDecimal(pieceRect[3].ToString());
//Remove Old Price Field
form.RemoveField(newPieceP.ToString());
//In with the new
TextField PieceField = new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)llxPiece, (float)llyPiece, (float)urxPiece, (float)uryPiece), newPieceP.ToString())
{
Alignment = 1,
Text = "0.00"
};
PdfFormField fPiece = PieceField.GetTextField();
fPiece.SetAdditionalActions(PdfName.BL, PdfAction.JavaScript("this.getField('" + newTotalP + "').value = (parseFloat(this.getField('" + newPieceP + "').value) + parseFloat(this.getField('" + newToolP + "').value) + parseFloat(this.getField('" + newFixtureP + "').value) + parseFloat(this.getField('" + newSetupP + "').value));", stamper.Writer));
fPiece.SetAdditionalActions(PdfName.F, PdfAction.JavaScript("AFNumber_Format(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
fPiece.SetAdditionalActions(PdfName.K, PdfAction.JavaScript("AFNumber_Keystroke(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
stamper.AddAnnotation(fPiece, 1);
//ToolPrice Field
var llxTool = Convert.ToDecimal(toolRect[0].ToString());
var llyTool = Convert.ToDecimal(toolRect[1].ToString());
var urxTool = Convert.ToDecimal(toolRect[2].ToString());
var uryTool = Convert.ToDecimal(toolRect[3].ToString());
//Remove Old Price Field
form.RemoveField(newToolP.ToString());
//In with the new
TextField ToolField = new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)llxTool, (float)llyTool, (float)urxTool, (float)uryTool), newToolP.ToString())
{
Alignment = 1,
Text = "0.00"
};
PdfFormField fTool = ToolField.GetTextField();
fTool.SetAdditionalActions(PdfName.BL, PdfAction.JavaScript("this.getField('" + newTotalP + "').value = (parseFloat(this.getField('" + newPieceP + "').value) + parseFloat(this.getField('" + newToolP + "').value) + parseFloat(this.getField('" + newFixtureP + "').value) + parseFloat(this.getField('" + newSetupP + "').value));", stamper.Writer));
fTool.SetAdditionalActions(PdfName.F, PdfAction.JavaScript("AFNumber_Format(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
fTool.SetAdditionalActions(PdfName.K, PdfAction.JavaScript("AFNumber_Keystroke(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
stamper.AddAnnotation(fTool, 1);
//FixturePrice Field
var llxFixture = Convert.ToDecimal(fixtureRect[0].ToString());
var llyFixture = Convert.ToDecimal(fixtureRect[1].ToString());
var urxFixture = Convert.ToDecimal(fixtureRect[2].ToString());
var uryFixture = Convert.ToDecimal(fixtureRect[3].ToString());
//Remove Old Price Field
form.RemoveField(newFixtureP.ToString());
//In with the new
TextField FixtureField = new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)llxFixture, (float)llyFixture, (float)urxFixture, (float)uryFixture), newFixtureP.ToString())
{
Alignment = 1,
Text = "0.00"
};
PdfFormField fFixture = FixtureField.GetTextField();
fFixture.SetAdditionalActions(PdfName.BL, PdfAction.JavaScript("this.getField('" + newTotalP + "').value = (parseFloat(this.getField('" + newPieceP + "').value) + parseFloat(this.getField('" + newToolP + "').value) + parseFloat(this.getField('" + newFixtureP + "').value) + parseFloat(this.getField('" + newSetupP + "').value));", stamper.Writer));
fFixture.SetAdditionalActions(PdfName.F, PdfAction.JavaScript("AFNumber_Format(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
fFixture.SetAdditionalActions(PdfName.K, PdfAction.JavaScript("AFNumber_Keystroke(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
stamper.AddAnnotation(fFixture, 1);
//SetupPrice Field
var llxSetup = Convert.ToDecimal(setupRect[0].ToString());
var llySetup = Convert.ToDecimal(setupRect[1].ToString());
var urxSetup = Convert.ToDecimal(setupRect[2].ToString());
var urySetup = Convert.ToDecimal(setupRect[3].ToString());
//Remove Old Price Field
form.RemoveField(newSetupP.ToString());
//In with the new
TextField setupField = new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)llxSetup, (float)llySetup, (float)urxSetup, (float)urySetup), newSetupP.ToString())
{
Alignment = 1,
Text = "0.00"
};
PdfFormField fSetup = setupField.GetTextField();
fSetup.SetAdditionalActions(PdfName.BL, PdfAction.JavaScript("this.getField('" + newTotalP + "').value = (parseFloat(this.getField('" + newPieceP + "').value) + parseFloat(this.getField('" + newToolP + "').value) + parseFloat(this.getField('" + newFixtureP + "').value) + parseFloat(this.getField('" + newSetupP + "').value));", stamper.Writer));
fSetup.SetAdditionalActions(PdfName.F, PdfAction.JavaScript("AFNumber_Format(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
fSetup.SetAdditionalActions(PdfName.K, PdfAction.JavaScript("AFNumber_Keystroke(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
stamper.AddAnnotation(fSetup, 1);
var llxTotal = Convert.ToDecimal(totalRect[0].ToString());
var llyTotal = Convert.ToDecimal(totalRect[1].ToString());
var urxTotal = Convert.ToDecimal(totalRect[2].ToString());
var uryTotal = Convert.ToDecimal(totalRect[3].ToString());
form.RemoveField(newTotalP.ToString());
TextField TotalField = new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)llxTotal, (float)llyTotal, (float)urxTotal, (float)uryTotal), newTotalP.ToString())
{
Alignment = 1
};
PdfFormField fTotal = TotalField.GetTextField();
fTotal.SetAdditionalActions(PdfName.BL, PdfAction.JavaScript("this.getField('" + newTotalP + "').value = (parseFloat(this.getField('" + newPieceP + "').value) + parseFloat(this.getField('" + newToolP + "').value) + parseFloat(this.getField('" + newFixtureP + "').value) + parseFloat(this.getField('" + newSetupP + "').value));", stamper.Writer));
fTotal.SetAdditionalActions(PdfName.F, PdfAction.JavaScript("AFNumber_Format(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
fTotal.SetAdditionalActions(PdfName.K, PdfAction.JavaScript("AFNumber_Keystroke(2, 0, 0, 0, '\u0024', true);", stamper.Writer));
stamper.AddAnnotation(fTotal, 1);
stamper.AcroFields.GenerateAppearances = true;
//close up shop and return the new doc in memory
stamper.Close();
reader.Close();
return baos.ToArray();
}
感谢你的帮助Bruno,onBlur确实是我需要的。