我正在使用PDF
通过AcroFields
应用填充包含iTextSharp
的Windows Forms
模板。数据通过多个comboBoxes
接口填充如下:
string template = path1 + @"\Template1.pdf";
PdfReader pdfreader = new PdfReader(template);
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, iTextSharp.text.pdf.AcroFields.Item> de in
pdfreader.AcroFields.Fields)
{
sb.Append(de.Key.ToString() + Environment.NewLine);
}
string newPDF = path + @"\"name".pdf";
PdfStamper pdfstamper = new PdfStamper(pdfreader, new FileStream(newPDF,
FileMode.Create));
AcroFields pdffields = pdfstamper.AcroFields;
pdffields.SetField("ProductText", product.SelectedItem.ToString());
pdffields.SetField("indexText", index.SelectedItem.ToString());
.
.
.
pdfstamper.FormFlattening = true;
pdfstamper.Close();
PDF
的结果如下图所示:
但问题是:当没有选择Grade
时(如上图所示),我可以移除整个Grade
行,但这将在PDF
中留下一个空白空白空间,如下图所示:
删除扁平空场的空白空间有哪些可能的方法?它是通过调整空间后面的内容来实现的吗?谢谢。
OP在对该问题的评论中表示
我可以处理标签问题,但我怎样才能移动下面的字段?
因此,以下代码仅处理字段。
因此,我们假设您在将字段设置为字段之前检查字段的值。如果值为空,则不设置字段值,而是调用如下方法向上移动该字段下方的每个字段:
void MoveUp(PdfStamper stamper, String fieldName, int pageNumber)
{
AcroFields fields = stamper.AcroFields;
IList<AcroFields.FieldPosition> positions = fields.GetFieldPositions(fieldName);
foreach (AcroFields.FieldPosition position in positions)
{
if (position.page == pageNumber)
{
IList<float> fieldYsBelowField = new List<float>();
PdfDictionary pageDict = stamper.Reader.GetPageN(pageNumber);
PdfArray annots = pageDict.GetAsArray(PdfName.ANNOTS);
for (int i = 0; i < annots.Size; i++)
{
PdfDictionary annot = annots.GetAsDict(i);
PdfArray rect = annot.GetAsArray(PdfName.RECT);
if (((PdfNumber)rect[1]).FloatValue < position.position.Bottom)
{
fieldYsBelowField.Add(((PdfNumber)rect[1]).FloatValue);
}
}
if (fieldYsBelowField.Count > 0)
{
float offset = position.position.Bottom - fieldYsBelowField.Max();
for (int i = 0; i < annots.Size; i++)
{
PdfDictionary annot = annots.GetAsDict(i);
PdfArray rect = annot.GetAsArray(PdfName.RECT);
if (((PdfNumber)rect[1]).FloatValue < position.position.Bottom)
{
rect[1] = new PdfNumber(((PdfNumber)rect[1]).FloatValue + offset);
rect[3] = new PdfNumber(((PdfNumber)rect[3]).FloatValue + offset);
}
}
}
}
}
}
你会得到你想要的。
例如。如果对于某些单页形成以下代码
AcroFields fields = stamper.AcroFields;
fields.SetField("Product", "Product1");
fields.SetField("Index", "XQAA-0000-000");
fields.SetField("Quality", "USP,");
fields.SetField("Grade", "SomeGrade");
fields.SetField("Customer", "Customer1");
fields.SetField("Market", "England, Germany");
结果是
和
AcroFields fields = stamper.AcroFields;
fields.SetField("Product", "Product1");
fields.SetField("Index", "XQAA-0000-000");
fields.SetField("Quality", "USP,");
fields.SetField("Customer", "Customer1");
fields.SetField("Market", "England, Germany");
结果是
然后
AcroFields fields = stamper.AcroFields;
fields.SetField("Product", "Product1");
fields.SetField("Index", "XQAA-0000-000");
fields.SetField("Quality", "USP,");
MoveUp(stamper, "Grade", 1);
fields.SetField("Customer", "Customer1");
fields.SetField("Market", "England, Germany");
结果是
在对OP提出的问题的评论中
我可以指定要移位的字段而不是移动所有字段以下吗? [...]假设我只想将Customer1转移到SomeGrade的位置。
帮助程序更简单:
void MoveUp(PdfStamper stamper, String fieldName, String moveFieldName, int pageNumber)
{
AcroFields fields = stamper.AcroFields;
IList<AcroFields.FieldPosition> positions = fields.GetFieldPositions(fieldName);
foreach (AcroFields.FieldPosition position in positions)
{
if (position.page == pageNumber)
{
Item moveFieldItem = fields.GetFieldItem(moveFieldName);
for (int i = 0; i < moveFieldItem.Size; i++)
{
if (moveFieldItem.GetPage(i) == pageNumber)
{
PdfDictionary annot = moveFieldItem.GetWidget(i);
PdfArray rect = annot.GetAsArray(PdfName.RECT);
float offset = position.position.Bottom - ((PdfNumber)rect[1]).FloatValue;
rect[1] = new PdfNumber(((PdfNumber)rect[1]).FloatValue + offset);
rect[3] = new PdfNumber(((PdfNumber)rect[3]).FloatValue + offset);
break;
}
}
}
}
}
使用这种方法,
AcroFields fields = stamper.AcroFields;
fields.SetField("Product", "Product1");
fields.SetField("Index", "XQAA-0000-000");
fields.SetField("Quality", "USP,");
MoveUp(stamper, "Grade", "Customer", 1);
fields.SetField("Customer", "Customer1");
fields.SetField("Market", "England, Germany");
结果是