我有一个带有 AcroFields 的 PDF。有些字段是多行字段。我需要用给定的文本填充 AcroFields,并用“*”(或预定义的字符/字符串)填充字段中的任何剩余空间。我可以使用 iText 添加文本,但不知道如何计算要添加的适量填充物。
请你能建议我如何做到这一点。谢谢你。
我写的代码是:
public string CreatePdf(IDictionary<FieldKey, string> dictionary, string template, string saveAs)
{
// Create new PDF from template
using (PdfReader reader = new PdfReader(template))
using (FileStream stream = new FileStream(saveAs, FileMode.Create, FileAccess.ReadWrite))
using (PdfStamper stamper = new PdfStamper(reader, stream))
{
// Populate PDF fields from dictionary
AcroFields formFields = stamper.AcroFields;
foreach (KeyValuePair<FieldKey, string> dataField in dictionary)
{
switch (dataField.Key.FieldType)
{
case FieldType.Text:
string fieldValue = dataField.Value;
// Add filler if a filler is set
if (!String.IsNullOrWhiteSpace(dataField.Key.FillRight))
{
fieldValue = GetTextWithFiller(formFields, dataField.Key.FieldName, fieldValue, dataField.Key.FillRight);
}
// Text field
if (!formFields.SetField(dataField.Key.FieldName, fieldValue))
throw new InvalidDataException(String.Format("Invalid Template Field: {0} in Template: {1}", dataField.Key.FieldName, template));
break;
case FieldType.Image:
// Image field
PlaceImage(formFields, dataField);
break;
case FieldType.Barcode2Of5:
// 2 of 5 Barcode
PlaceBarcode2Of5(dataField.Value, stamper);
break;
case FieldType.Barcode128:
// 2 of 5 Barcode
PlaceBarcode128(dataField.Value, stamper);
break;
default:
throw new InvalidDataException(String.Format("Invalid data filed type : {0}", dataField.Key.FieldType));
}
}
// Save PDF
reader.RemoveUnusedObjects();
stamper.FormFlattening = true;
stamper.Close();
}
return saveAs;
}
以及获取填充物的方法,它没有按我的预期工作:
private static string GetTextWithFiller(AcroFields fields, string fieldName, string text, string filler)
{
// Get the size of the rectangle that defines the field
AcroFields.FieldPosition fieldPosition = fields.GetFieldPositions(fieldName)[0];
Rectangle rect = fieldPosition.position;
// Get field font
PdfDictionary merged = fields.GetFieldItem(fieldName).GetMerged(0);
TextField textField = new TextField(null, null, null);
fields.DecodeGenericDictionary(merged, textField);
Font fieldFont = new Font(textField.Font);
Chunk whatWeHave = new Chunk(text, fieldFont);
float textWidth = whatWeHave.GetWidthPoint();
// See how far the text field is filled with give text
float textEndPoint = rect.Left + textWidth;
float rectBottom = rect.Bottom;
float rectRight = rect.Right;
float rectTop = rect.Top;
// How many rows to fill
int textRows = Convert.ToInt32(rect.Height / fieldFont.CalculatedSize);
float totalCharactersWeCanFit = rect.Width * textRows;
if (textWidth < totalCharactersWeCanFit)
{
// Get the width of filler character
Chunk fillCharWidth = new Chunk(filler, fieldFont);
// Available gap
float gap = totalCharactersWeCanFit - textWidth;
// How much filler required
int fillAmount = Convert.ToInt32(gap / fillCharWidth.GetWidthPoint());
// Fill with filler
StringBuilder tempString = new StringBuilder();
tempString.Append(text);
for (int n = 0; n < fillAmount; ++n)
{
tempString.Append(filler);
}
text = tempString.ToString();
}
return text;
}