Fill PDF template acrofield with HTML formatted text using iTextSharp
Я использую iTextSharp
to fill in a PDF
шаблон. The data I am using is kept in a database and is HTML
отформатирована. My problem is that when I load the AcroField
with this text I get it to do the line breaks, but no bold nor italicizing. Я уже пытался использовать HtmlWorker
, but all the examples online show it being used to convert HTML
к PDF
but I am trying to set an AcroField
in a PDF template. Любая помощь будет оценена.
2 ответа
Потратив несколько дней на просмотр форумов и исходного кода iTextsharp, я нашел решение. Вместо того, чтобы заполнять Acrofield текстом в формате HTML, я использовал ColumnText. Я анализирую HTML-текст и загружаю элементы в абзац. Затем добавьте абзац в ColumnText. Затем я наложил ColumnText поверх того, где должен быть Acrofield, используя координаты поля.
public void AddHTMLToContent(String htmlText,PdfContentByte contentBtye,IList<AcroFields.FieldPosition> pos)
{
Paragraph par = new Paragraph();
ColumnText c1 = new ColumnText(contentBtye);
try
{
List<IElement> elements = HTMLWorker.ParseToList(new StringReader(htmlText),null);
foreach (IElement element in elements)
{
par.Add(element);
}
c1.AddElement(par);
c1.SetSimpleColumn(pos[0].position.Left, pos[0].position.Bottom, pos[0].position.Right, pos[0].position.Top);
c1.Go(); //very important!!!
}
catch (Exception ex)
{
throw;
}
}
Вот пример вызова этой функции.
string htmlText ="<b>Hello</b><br /><i>World</i>";
IList<AcroFields.FieldPosition> pos = form.GetFieldPositions("Field1");
//Field1 is the name of the field in the PDF Template you are trying to fill/overlay
AddHTMLToContent(htmlText, stamp.GetOverContent(pos[0].page), pos);
//stamp is the PdfStamper in this example
Одна вещь, с которой я столкнулся, это то, что у моего Acrofield был предопределенный размер шрифта. Так как эта функция устанавливает ColumnText сверху на поле, любые изменения шрифта должны быть сделаны в функции. Вот пример изменения размера шрифта:
public void AddHTMLToContent(String htmlText,PdfContentByte contentBtye,IList<AcroFields.FieldPosition> pos)
{
Paragraph par = new Paragraph();
ColumnText c1 = new ColumnText(contentBtye);
try
{
List<IElement> elements = HTMLWorker.ParseToList(new StringReader(htmlText),null);
foreach (IElement element in elements)
{
foreach (Chunk chunk in element.Chunks)
{
chunk.Font.Size = 14;
}
}
par.Add(elements[0]);
c1.AddElement(par);
c1.SetSimpleColumn(pos[0].position.Left, pos[0].position.Bottom, pos[0].position.Right, pos[0].position.Top);
c1.Go();//very important!!!
}
catch (Exception ex)
{
throw;
}
}
Я надеюсь, что это сэкономит кому-то время и энергию в будущем.
Итак, мне пришлось немного подправить этот код за последние несколько месяцев, и я нашел лучший / менее подходящий способ сделать это.
public void Final(string text,string fieldName,string filename)
{
iTextSharp.text.pdf.PdfReader reader = null;
iTextSharp.text.pdf.PdfStamper stamp = null;
reader = new PdfReader(file path to template);
stamp = new PdfStamper(reader, new FileStream(path to new file, FileMode.CreateNew));
AcroFields form = stamp.AcroFields;
//get the position of the field
IList<AcroFields.FieldPosition> pos = form.GetFieldPositions(fieldName);
//tell itextSharp to overlay this content
PdfContentByte contentBtye = stamp.GetOverContent(pos[0].page);
//create a new paragraph
Paragraph par = new Paragraph();
//parse html
List<IElement> elements = HTMLWorker.ParseToList(new StringReader(text), null);
for (int k = 0; k < elements.Count; k++)
{
par.Add((IElement)elements[k]);
}
//create a ColumnText to hold the paragraph and set position to the position of the field
ColumnText ct = new ColumnText(contentBtye);
ct.SetSimpleColumn(pos[0].position.Left, pos[0].position.Bottom, pos[0].position.Right, pos[0].position.Top);
ct.AddElement(par);
ct.Go();
stamp.Close();
reader.Close();
}