合并表单后,iText字段将无法计算
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并表单后,iText字段将无法计算相关的知识,希望对你有一定的参考价值。
我正在使用此脚本循环访问用户文件并填写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: empDetails.pdf";
//final multi page quote
string finishedQuote = @"C: empQuote.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的链接
答案
因此,我能够正确计算的唯一方法是用新的字段替换现有字段:
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);
//SetupPri以上是关于合并表单后,iText字段将无法计算的主要内容,如果未能解决你的问题,请参考以下文章