使用ABCPDF添加TextField非常简单:
public FormField AddTextField(string inRect, string inName, string inText)
{
int fieldId = mDoc.AddObject("<</Type /Annot /Subtype /Widget /F 4 /FT /Tx /Ff 4096 /Q 1>>");
mDoc.SetInfo(fieldId, "/V:Text", inText);
RegisterField(fieldId, inName, inRect);
return new FormField(fieldId, mDoc);
}
以此为实施:
FormField text = AddTextField("40 530 300 580", "TextField1", "Hello World!");
text.DefaultAppearance = "/TimesRoman 36 Tf 0 0 1 rg";
text.BorderColor = "0 0 0";
text.FillColor = "220 220 220";
text.TextAlign = "Left";
如果我需要添加两个具有相同名称的字段,它会更复杂一些:
public int AddGroupField(FormField[] inKids, string inName, string inValue)
{
if (inKids.Length == 0)
throw new Exception("Cannot have a group field with no kids");
string ft = null, dv = null;
int fieldId = mDoc.AddObject("<< /Kids [] >>");
foreach (FormField kid in inKids)
{
mDoc.SetInfo(fieldId, "/Kids[]:Ref", kid.Id.ToString());
mDoc.SetInfo(kid.Id, "/Parent:Ref", fieldId);
if (ft == null)
ft = mDoc.GetInfo(kid.Id, "/FT");
if (dv == null)
dv = mDoc.GetInfo(kid.Id, "/DV");
mDoc.SetInfo(kid.Id, "/FT:Del", "");
mDoc.SetInfo(kid.Id, "/V:Del", "");
mDoc.SetInfo(kid.Id, "/DV:Del", "");
}
mDoc.SetInfo(fieldId, "/FT", ft);
mDoc.SetInfo(fieldId, "/T:Text", inName);
mDoc.SetInfo(fieldId, "/V:Text", inValue);
if (dv != null)
mDoc.SetInfo(fieldId, "/DV:Text", dv);
int eid = mDoc.GetInfoInt(mDoc.Root, "/AcroForm:Ref");
mDoc.SetInfo(eid, "/Fields*[]:Ref", fieldId);
return fieldId;
}
以此为实施:
FormField[] kids = new FormField[2];
kids[0] = AddTextField("40 230 300 280", null, null);
kids[1] = AddTextField("40 170 300 220", null, null);
int id = AddGroupField(kids, "TextField1", "Hello World!");
但是,我在将TextField添加到PDF中时遇到问题,其中TextField已存在同名。因此,例如,如果我的PDF已经有一个名为&#34; TextField1&#34;然后我想添加另一个具有相同名称的字段,上述任何实现都不起作用。
答案 0 :(得分:3)
我能够从ABCPDF支持中得到答案。正如您所看到的,这不是一个简单的过程。我不确定任何人都可以自己解决这个问题,而无需花费数月和数月对PDF规范和ABCPDF产品进行研究。
public FormField AddTextField(string inRect, string inName, string inText)
{
bool fieldAlreadyExists = mDoc.Form[inName] != null;
int fieldId = mDoc.AddObject("<</Type /Annot /Subtype /Widget /F 4 /FT /Tx /Ff 4096 /Q 1>>");
mDoc.SetInfo(fieldId, "/V:Text", inText);
RegisterField(fieldId, inName, inRect);
var field = new FormField(fieldId, mDoc);
if (fieldAlreadyExists)
{
InteractiveForm form = new InteractiveForm(mDoc);
form.AddFieldIntoExistingGroup(field, true);
}
return field;
}
private bool AddFieldIntoExistingGroup(FormField field, bool refreshForm)
{
bool duplicatesFound = false;
int acroFormID = mDoc.GetInfoInt(mDoc.Root, "/AcroForm:Ref");
int parentID = mDoc.GetInfoInt(field.Id, "/Parent:Ref");
ArrayAtom kids;
if (parentID > 0)
{
kids = mDoc.ObjectSoup.Catalog.Resolve(Atom.GetItem(mDoc.ObjectSoup[parentID].Atom, "Kids")) as ArrayAtom;
}
else
{
kids = mDoc.ObjectSoup.Catalog.Resolve(Atom.GetItem(mDoc.ObjectSoup[acroFormID].Atom, "Fields")) as ArrayAtom;
}
Dictionary<string, List<IndirectObject>> items = new Dictionary<string, List<IndirectObject>>();
for (int i = 0; i < kids.Count; i++)
{
IndirectObject io = mDoc.ObjectSoup.Catalog.ResolveObj(kids[i]);
if (io == null)
{
continue; // shouldn't really happen
}
string name = mDoc.GetInfo(io.ID, "/T:Text");
if (!items.ContainsKey(name))
{
items[name] = new List<IndirectObject>();
}
items[name].Add(io);
}
foreach (KeyValuePair<string, List<IndirectObject>> pair in items)
{
if (pair.Value.Count > 1)
{
duplicatesFound = true;
// shift field down to be a child of a new field node
int id = mDoc.AddObject("<< >>");
if (parentID > 0)
{
mDoc.SetInfo(parentID, "/Kids[]:Ref", id);
mDoc.SetInfo(id, "/Parent:Ref", parentID);
}
else
{
mDoc.SetInfo(acroFormID, "/Fields[]:Ref", id);
}
string[] dictEntries = new[] { "/FT", "/T", "/TU", "/Ff", "/V", "/DV" };
foreach (IndirectObject io in pair.Value)
{
foreach (string dictEntry in dictEntries)
{
string val = mDoc.GetInfo(io.ID, dictEntry);
if (!string.IsNullOrEmpty(val))
{
mDoc.SetInfo(id, dictEntry, val);
mDoc.SetInfo(io.ID, dictEntry + ":Del", "");
}
}
ArrayRemoveOneRefAtom(kids, io.ID);
mDoc.SetInfo(id, "/Kids[]:Ref", io.ID);
mDoc.SetInfo(io.ID, "/Parent:Ref", id);
}
}
}
if ((refreshForm) && (duplicatesFound))
{
mDoc.Form.Refresh();
}
return duplicatesFound;
}
private static bool ArrayRemoveOneRefAtom(ArrayAtom array, int id)
{
if (array != null)
{
for (int i = 0; i < array.Count; i++)
{
RefAtom refAtom = array[i] as RefAtom;
if ((refAtom != null) && (refAtom.ID == id))
{
ArrayRemoveAt(array, i);
return true;
}
}
}
return false;
}
private static void ArrayRemoveAt(ArrayAtom array, int index)
{
if (index == 0)
{ // Workaround for bug in some versions of ABCpdf
Atom[] copy = new Atom[array.Count];
array.CopyTo(copy, 0);
array.Clear();
for (int i = 1; i < copy.Length; i++)
array.Add(copy[i]);
}
else
{
array.RemoveAt(index);
}
}