In the following code , chinese font( contained html text) doesnot display in pdf generated.
I also try styles and font in this method. Please help to solve this problem.
Thanks in advance to all.
public static bool GeneratedPDF(string strHTMLText, string filename, string action, string rpttype)
{
bool blnReturn = false;
string fontpath = HttpContext.Current.Server.MapPath("~/files/fonts/");
string filepath = HttpContext.Current.Server.MapPath("~/files/pdf/");
BaseFont customfont = BaseFont.CreateFont(fontpath + "simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(customfont, 12);
//List<iTextSharp.text.IElement> htmlarraylist = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(new System.IO.StringReader(strHTMLText), null);
iTextSharp.text.Document document = new iTextSharp.text.Document();
if (rpttype.Trim().ToUpper() == "REPORT")
document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A2.Rotate());
else if (rpttype.Trim().ToUpper() == "GRID")
document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4.Rotate());
else
document = new iTextSharp.text.Document(iTextSharp.text.PageSize.LETTER);
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new FileStream(filepath + "\\" + filename, FileMode.Create));
document.Open();
iTextSharp.text.html.simpleparser.StyleSheet styles = new iTextSharp.text.html.simpleparser.StyleSheet();
styles.LoadTagStyle("body", "font-family", "verdana");
styles.LoadStyle("body", "font-size", "5px");
List<iTextSharp.text.IElement> htmlarraylist = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(new System.IO.StringReader(strHTMLText), styles);
for (int k = 0; k < htmlarraylist.Count; k++)
{
document.Add((IElement)htmlarraylist[k]);
}
iTextSharp.text.Paragraph p = new iTextSharp.text.Paragraph();
p.InsertRange(0, htmlarraylist);
p.Font = font; // font does not work
document.Add(p);
document.Close();
blnReturn = true;
return blnReturn;
}
You set the StyleSheet wrong. It should be something like this:
string html = #"
<html><body>
<p>使用iText做PDF文件輸出</p>
<p>使用iText做PDF文件輸出</p>
<p>使用iText做PDF文件輸出</p>
<p>使用iText做PDF文件輸出</p>
<p>使用iText做PDF文件輸出</p>
</body></html>
";
FontFactory.Register("c:/windows/fonts/ARIALUNI.TTF");
StyleSheet style = new StyleSheet();
style.LoadTagStyle("body", "face", "Arial Unicode MS");
style.LoadTagStyle("body", "encoding", BaseFont.IDENTITY_H);
using (Document document = new Document()) {
PdfWriter writer = PdfWriter.GetInstance(
document, Response.OutputStream
);
document.Open();
foreach(IElement element in HTMLWorker.ParseToList(
new StringReader(html.ToString()), style))
{
document.Add(element);
}
}
You need to change the third parameter of LoadTagStyle() above to the correct name of the specific font you're using. In other words, replace "Arial Unicode MS" above with the name/value for your font. Or you can use the font above too.
Related
I want to change the font of the content to TIMES NEW roman
iTextSharp.text.html.simpleparser.HTMLWorker hw = new iTextSharp.text.html.simpleparser.HTMLWorker(textSharpDocument);
#pragma warning restore 612, 618
String[] content = letterContent.Split(new string[] { AppUtil.GetAppSettings(AppConfigKey.ReceiptLetterPDFSeparator) }, StringSplitOptions.None);
//Add Content to File
if (content.Length > AppConstants.DEFAULT_PARAMETER_ZERO)
{
string imageFolderPath = AppUtil.GetAppSettings(AppConfigKey.UploadedImageFolderPath);
for (int counter = 0; counter < content.Length - 1; counter++)
{
textSharpDocument.Add(new Paragraph());
if (!String.IsNullOrEmpty(imageUrlList[counter]))
{
string imageURL = imageFolderPath + imageUrlList[counter];
textSharpDocument.Add(new Paragraph());
string imagePath = AppUtil.GetAppSettings(AppConfigKey.ParticipantCommunicationFilePhysicalPath) + imageUrlList[counter];
imagePath = imagePath.Replace(#"\", "/");
if (File.Exists(imagePath))
{
iTextSharp.text.Image png = iTextSharp.text.Image.GetInstance(imageURL);
imageLocationIDs[counter] = imageLocationIDs[counter] != null ? AppUtil.ConvertToInt(imageLocationIDs[counter], AppConstants.DEFAULT_PARAMETER_ONE) : AppUtil.ConvertEnumToInt(AppImageLocation.Left);
if (imageLocationIDs[counter] == AppUtil.ConvertEnumToInt(AppImageLocation.Left))
png.Alignment = iTextSharp.text.Image.ALIGN_LEFT;
if (imageLocationIDs[counter] == AppUtil.ConvertEnumToInt(AppImageLocation.Right))
png.Alignment = iTextSharp.text.Image.ALIGN_RIGHT;
if (imageLocationIDs[counter] == AppUtil.ConvertEnumToInt(AppImageLocation.Center))
png.Alignment = iTextSharp.text.Image.ALIGN_CENTER;
textSharpDocument.Add(png);
}
}
hw.Parse(new StringReader(content[counter]));
hw.EndElement("</html>");
hw.Parse(new StringReader(AppUtil.GetAppSettings(AppConfigKey.ReceiptLetterPDFSeparator)));
}
}
You could set at basefont something like this
BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
Font times = new Font(bfTimes, 12, Font.ITALIC, Color.BLACK);
Document doc = new Document();
PdfWriter.GetInstance(doc, new FileStream("c:\\Font.pdf", FileMode.Create));
doc.Open();
doc.Add(new Paragraph("This is a test using Times Roman", times));
doc.Close();
I have a report that I'm trying to generate using iTextSharp that includes html text entered by the user using tinymce on my web page. I then have a report and I want to insert a phrase that uses their markup.
While basic markup such as bold and underline work, lists, indents, alignment do not. Any suggestions short of writing my own little html to pdf parser?
My code:
internal static Phrase GetPhraseFromHtml(string html, string fontName, int fontSize)
{
var returnPhrase = new Phrase();
html.Replace(Environment.NewLine, String.Empty);
//the string has to be well formated html in order to work and has to specify the font since
//specifying the font in the phrase overrides the formatting of the html tags.
string pTag = string.Format("<p style='font-size: {0}; font-family:{1}'>", fontSize, fontName);
if (html.StartsWith("<p>"))
{
html = html.Replace("<p>", pTag);
}
else
{
html = pTag + html + "</p>";
}
html
= "<html><body>"
+ html
+ "</body></html>";
using (StringWriter sw = new StringWriter())
{
using (System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(sw))
{
var xmlWorkerHandler = new XmlWorkerHandler();
//Bind a reader to our text
using (TextReader textReader = new StringReader(html))
{
//Parse
XMLWorkerHelper.GetInstance().ParseXHtml(xmlWorkerHandler, textReader);
}
var addPhrase = new Phrase();
var elementText = new StringBuilder();
bool firstElement = true;
//Loop through each element
foreach (var element in xmlWorkerHandler.elements)
{
if (firstElement)
{
firstElement = false;
}
else
{
addPhrase.Add(new Chunk("\n"));
}
//Loop through each chunk in each element
foreach (var chunk in element.Chunks)
{
addPhrase.Add(chunk);
}
returnPhrase.Add(addPhrase);
addPhrase = new Phrase();
}
return returnPhrase;
}
}
}
I've been working on my site, and trying to create an Export to Word. The export works well, converting HTML string to DOCX.
I'm trying to figure out how I can adjust the Line Spacing. By Default Word is adding 8pt Spacing After and setting the Line Spacing to double. I would prefer 0 and Single.
Here is the Function I created to Save a Word Document:
private static void SaveDOCX(string fileName, string BodyText, bool isLandScape, double rMargin, double lMargin, double bMargin, double tMargin)
{
string htmlSectionID = "Sect1";
//Creating a word document using the the Open XML SDK 2.0
WordprocessingDocument document = WordprocessingDocument.Create(fileName, WordprocessingDocumentType.Document);
//create a paragraph
MainDocumentPart mainDocumenPart = document.AddMainDocumentPart();
mainDocumenPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
Body documentBody = new Body();
mainDocumenPart.Document.Append(documentBody);
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<html><head></head><body>" + BodyText + "</body></html>"));
// Create alternative format import part.
AlternativeFormatImportPart formatImportPart = mainDocumenPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html, htmlSectionID);
//ms.Seek(0, SeekOrigin.Begin);
// Feed HTML data into format import part (chunk).
formatImportPart.FeedData(ms);
AltChunk altChunk = new AltChunk();
altChunk.Id = htmlSectionID;
mainDocumenPart.Document.Body.Append(altChunk);
/*
inch equiv = 1440 (1 inch margin)
*/
double width = 8.5 * 1440;
double height = 11 * 1440;
SectionProperties sectionProps = new SectionProperties();
PageSize pageSize;
if (isLandScape)
{
pageSize = new PageSize() { Width = (UInt32Value)height, Height = (UInt32Value)width, Orient = PageOrientationValues.Landscape };
}
else
{
pageSize = new PageSize() { Width = (UInt32Value)width, Height = (UInt32Value)height, Orient = PageOrientationValues.Portrait };
}
rMargin = rMargin * 1440;
lMargin = lMargin * 1440;
bMargin = bMargin * 1440;
tMargin = tMargin * 1440;
PageMargin pageMargin = new PageMargin() { Top = (Int32)tMargin, Right = (UInt32Value)rMargin, Bottom = (Int32)bMargin, Left = (UInt32Value)lMargin, Header = (UInt32Value)360U, Footer = (UInt32Value)360U, Gutter = (UInt32Value)0U };
sectionProps.Append(pageSize);
sectionProps.Append(pageMargin);
mainDocumenPart.Document.Body.Append(sectionProps);
//Saving/Disposing of the created word Document
document.MainDocumentPart.Document.Save();
document.Dispose();
}
In searching, I found this code:
SpacingBetweenLines spacing = new SpacingBetweenLines() { Line = "240", LineRule = LineSpacingRuleValues.Auto, Before = "0", After = "0" };
I've placed it many places in my function, but I can't seem to find the correct place to Append this setting.
I worked on the function trying to set the spacing in code, but wasn't able to remove the spacing. I decided to try creating a Template Word Document and setting the spacing in that document.
I copy the template.docx file, creating the one I will use, then use the adjusted function below to add the HTML string:
private static void SaveDOCX(string fileName, string BodyText, bool isLandScape, double rMargin, double lMargin, double bMargin, double tMargin)
{
WordprocessingDocument document = WordprocessingDocument.Open(fileName, true);
MainDocumentPart mainDocumenPart = document.MainDocumentPart;
//Place the HTML String into a MemoryStream Object
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<html><head></head><body>" + BodyText + "</body></html>"));
//Assign an HTML Section for the String Text
string htmlSectionID = "Sect1";
// Create alternative format import part.
AlternativeFormatImportPart formatImportPart = mainDocumenPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html, htmlSectionID);
// Feed HTML data into format import part (chunk).
formatImportPart.FeedData(ms);
AltChunk altChunk = new AltChunk();
altChunk.Id = htmlSectionID;
//Clear out the Document Body and Insert just the HTML string. (This prevents an empty First Line)
mainDocumenPart.Document.Body.RemoveAllChildren();
mainDocumenPart.Document.Body.Append(altChunk);
/*
Set the Page Orientation and Margins Based on Page Size
inch equiv = 1440 (1 inch margin)
*/
double width = 8.5 * 1440;
double height = 11 * 1440;
SectionProperties sectionProps = new SectionProperties();
PageSize pageSize;
if (isLandScape)
pageSize = new PageSize() { Width = (UInt32Value)height, Height = (UInt32Value)width, Orient = PageOrientationValues.Landscape };
else
pageSize = new PageSize() { Width = (UInt32Value)width, Height = (UInt32Value)height, Orient = PageOrientationValues.Portrait };
rMargin = rMargin * 1440;
lMargin = lMargin * 1440;
bMargin = bMargin * 1440;
tMargin = tMargin * 1440;
PageMargin pageMargin = new PageMargin() { Top = (Int32)tMargin, Right = (UInt32Value)rMargin, Bottom = (Int32)bMargin, Left = (UInt32Value)lMargin, Header = (UInt32Value)360U, Footer = (UInt32Value)360U, Gutter = (UInt32Value)0U };
sectionProps.Append(pageSize);
sectionProps.Append(pageMargin);
mainDocumenPart.Document.Body.Append(sectionProps);
//Saving/Disposing of the created word Document
document.MainDocumentPart.Document.Save();
document.Dispose();
}
By using the template file, the line spacing is correct.
For those that might find this function useful, here is the code that calls the function:
string filePath = "~/Content/Exports/Temp/";
string WordTemplateFile = HttpContext.Current.Server.MapPath("/Content/Templates/WordTemplate.docx");
string DestinationPath = HttpContext.Current.Server.MapPath(filePath);
string NewFileName = DOCXFileName + ".docx";
string destFile = System.IO.Path.Combine(DestinationPath, NewFileName);
System.IO.File.Copy(WordTemplateFile, destFile, true);
SaveDOCX(destFile, HTMLString, isLandScape, rMargin, lMargin, bMargin, tMargin);
You can't change the formatting because your code is only inserting HTML into a Word doc. To change the formatting, the HTML text needs to be converted to regular text and added to the Word doc as such. I was in a similar issue and using the HtmlToOpenXml library makes this quick and simple.
using HtmlToOpenXml;
Then the function:
protected virtual void createWord()
{
string html = "*myHtml*";
// Create WordProcessingDocument
WordprocessingDocument doc = WordprocessingDocument.Create(ms, WordprocessingDocumentType.Document);
MainDocumentPart mainPart = doc.MainDocumentPart;
if (mainPart == null)
mainPart = doc.AddMainDocumentPart();
Document document = doc.MainDocumentPart.Document;
if (document == null)
document = mainPart.Document = new Document();
Body body = mainPart.Document.Body;
if (body == null)
body = mainPart.Document.Body = new Body(new SectionProperties(new PageMargin() { Top = 1440, Right = 1440U, Bottom = 1440, Left = 1440U, Header = 720U, Footer = 720U, Gutter = 0U }));
// Convert Html to OpenXml
HtmlConverter converter = new HtmlConverter(mainPart);
converter.ParseHtml(html);
// Reformat paragraphs
ParagraphProperties pProps = new ParagraphProperties(new SpacingBetweenLines() { Line = "240", LineRule = LineSpacingRuleValues.Auto, Before = "0", After = "0" });
var paragraphs = doc.MainDocumentPart.Document.Body.Descendants<Paragraph>().ToList();
foreach (Paragraph p in paragraphs)
{
if (p != null)
p.PrependChild(pProps.CloneNode(true));
}
// Close the document handle
doc.Close();
}
I have a class that build the content for my table of contents and that works, fine and dandy.
Here's the code:
public void Build(string center,IDictionary<string,iTextSharp.text.Image> images)
{
iTextSharp.text.Image image = null;
XPathDocument rapportTekst = new XPathDocument(Application.StartupPath + #"..\..\..\RapportTemplates\RapportTekst.xml");
XPathNavigator nav = rapportTekst.CreateNavigator();
XPathNodeIterator iter;
iter = nav.Select("//dokument/brevhoved");
iter.MoveNext();
var logo = iTextSharp.text.Image.GetInstance(iter.Current.GetAttribute("url", ""));
iter = nav.Select("//dokument/gem_som");
iter.MoveNext();
string outputPath = iter.Current.GetAttribute("url", "")+center+".pdf";
iter = nav.Select("//dokument/titel");
iter.MoveNext();
this.titel = center;
Document document = new Document(PageSize.A4, 30, 30, 100, 30);
var outputStream = new FileStream(outputPath, FileMode.Create);
var pdfWriter = PdfWriter.GetInstance(document, outputStream);
pdfWriter.SetLinearPageMode();
var pageEventHandler = new PageEventHandler();
pageEventHandler.ImageHeader = logo;
pdfWriter.PageEvent = pageEventHandler;
DateTime timeOfReport = DateTime.Now.AddMonths(-1);
pageWidth = document.PageSize.Width - (document.LeftMargin + document.RightMargin);
pageHight = document.PageSize.Height - (document.TopMargin + document.BottomMargin);
document.Open();
var title = new Paragraph(titel, titleFont);
title.Alignment = Element.ALIGN_CENTER;
document.Add(title);
List<TableOfContentsEntry> _contentsTable = new List<TableOfContentsEntry>();
nav.MoveToRoot();
iter = nav.Select("//dokument/indhold/*");
Chapter chapter = null;
int chapterCount = 1;
while (iter.MoveNext())
{
_contentsTable.Add(new TableOfContentsEntry("Test", pdfWriter.CurrentPageNumber.ToString()));
XPathNodeIterator innerIter = iter.Current.SelectChildren(XPathNodeType.All);
chapter = new Chapter("test", chapterCount);
while(innerIter.MoveNext())
{
if (innerIter.Current.Name.ToString().ToLower().Equals("billede"))
{
image = images[innerIter.Current.GetAttribute("navn", "")];
image.Alignment = Image.ALIGN_CENTER;
image.ScaleToFit(pageWidth, pageHight);
chapter.Add(image);
}
if (innerIter.Current.Name.ToString().ToLower().Equals("sektion"))
{
string line = "";
var afsnit = new Paragraph();
line += (innerIter.Current.GetAttribute("id", "") + " ");
innerIter.Current.MoveToFirstChild();
line += innerIter.Current.Value;
afsnit.Add(line);
innerIter.Current.MoveToNext();
afsnit.Add(innerIter.Current.Value);
chapter.Add(afsnit);
}
}
chapterCount++;
document.Add(chapter);
}
document = CreateTableOfContents(document, pdfWriter, _contentsTable);
document.Close();
}
I'm then calling the method CreateTableOfContents(), and as such it is doing what it is supposed to do. Here's the code for the method:
public Document CreateTableOfContents(Document _doc, PdfWriter _pdfWriter, List<TableOfContentsEntry> _contentsTable)
{
_doc.NewPage();
_doc.Add(new Paragraph("Table of Contents", FontFactory.GetFont("Arial", 18, Font.BOLD)));
_doc.Add(new Chunk(Environment.NewLine));
PdfPTable _pdfContentsTable = new PdfPTable(2);
foreach (TableOfContentsEntry content in _contentsTable)
{
PdfPCell nameCell = new PdfPCell(_pdfContentsTable);
nameCell.Border = Rectangle.NO_BORDER;
nameCell.Padding = 6f;
nameCell.Phrase = new Phrase(content.Title);
_pdfContentsTable.AddCell(nameCell);
PdfPCell pageCell = new PdfPCell(_pdfContentsTable);
pageCell.Border = Rectangle.NO_BORDER;
pageCell.Padding = 6f;
pageCell.Phrase = new Phrase(content.Page);
_pdfContentsTable.AddCell(pageCell);
}
_doc.Add(_pdfContentsTable);
_doc.Add(new Chunk(Environment.NewLine));
/** Reorder pages so that TOC will will be the second page in the doc
* right after the title page**/
int toc = _pdfWriter.PageNumber - 1;
int total = _pdfWriter.ReorderPages(null);
int[] order = new int[total];
for (int i = 0; i < total; i++)
{
if (i == 0)
{
order[i] = 1;
}
else if (i == 1)
{
order[i] = toc;
}
else
{
order[i] = i;
}
}
_pdfWriter.ReorderPages(order);
return _doc;
}
The problem is however. I want to insert a page break before the table of contents, for the sake of reordering the pages, so that the table of contents is the first page, naturally. But the output of the pdf-file is not right.
Here's a picture of what it looks like:
It seems like the _doc.NewPage() in the CreateTableOfContents() method does not execute correctly. Meaning that the image and the table of contents is still on the same page when the method starts the reordering of pages.
EDIT: To clarify the above, the _doc.NewPage() gets executed, but the blank page is added after the picture and the table of contents.
I've read a couple of places that this could be because one is trying to insert a new page after an already blank page. But this is not the case.
I'll just link to the pdf files aswell, to better illustrate the problem.
The pdf with table of contents: with table of contents
The pdf without table of contents: without table of contents
Thank you in advance for your help :)
I am trying to display the "✔" character in a PDF using iTextSharp. However the character won't show up on the created PDF. Please help me on this.
Phrase phrase = new Phrase("A check mark: ");
Font zapfdingbats = new Font(Font.FontFamily.ZAPFDINGBATS);
phrase.Add(new Chunk("\u0033", zapfdingbats));
phrase.Add(" and more text");
document.Add(phrase);
Font Wingdings prints this character instead of "o".
You need to connect this font to your application, then apply this font to letter and embedd the font into pdf for compatibility.
This is my function (not cleaned) that I have used in one of my projects a while back.
please clean it up, but it has some essential features that you need. (I had my custom fonts (font1.ttf and font2.ttf) copied in the project directory)
I am hoping it will help you.
public void StartConvert(String originalFile, String newFile)
{
Document myDocument = new Document(PageSize.LETTER);
PdfWriter.GetInstance(myDocument, new FileStream(newFile, FileMode.Create));
myDocument.Open();
int totalfonts = FontFactory.RegisterDirectory("C:\\WINDOWS\\Fonts");
iTextSharp.text.Font content = FontFactory.GetFont("Pea Heather's Handwriting", 13);//13
iTextSharp.text.Font header = FontFactory.GetFont("assign", 16); //16
BaseFont customfont = BaseFont.CreateFont(#"font1.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
Font font = new Font(customfont, 13);
string s = " ";
myDocument.Add(new Paragraph(s, font));
BaseFont customfont2 = BaseFont.CreateFont(#"font2.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
Font font2 = new Font(customfont2, 16);
string s2 = " ";
myDocument.Add(new Paragraph(s2, font2));
try
{
try
{
using (StreamReader sr = new StreamReader(originalFile))
{
// Read and display lines from the file until the end of
// the file is reached.
String line;
while ((line = sr.ReadLine()) != null)
{
String newTempLine = "";
String[] textArray;
textArray = line.Split(' ');
newTempLine = returnSpaces(RandomNumber(0, 6)) + newTempLine;
int counterMax = RandomNumber(8, 12);
int counter = 0;
foreach (String S in textArray)
{
if (counter == counterMax)
{
Paragraph P = new Paragraph(newTempLine + Environment.NewLine, font);
P.Alignment = Element.ALIGN_LEFT;
myDocument.Add(P);
newTempLine = "";
newTempLine = returnSpaces(RandomNumber(0, 6)) + newTempLine;
}
newTempLine = newTempLine + returnSpaces(RandomNumber(1, 5)) + S;
counter++;
}
Paragraph T = new Paragraph(newTempLine, font2);
T.Alignment = Element.ALIGN_LEFT;
myDocument.Add(T);
}
}
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
}
catch (DocumentException de)
{
Console.Error.WriteLine(de.Message);
}
catch (IOException ioe)
{
Console.Error.WriteLine(ioe.Message);
}
try
{
myDocument.Close();
}
catch { }
}
Define font at master
protected static Font ZAPFDINGBATS(float size, bool bold = false, bool italic = false, bool underline = false, Color color = null)
=> new(StandardFonts.ZAPFDINGBATS, size, bold, italic, underline, color);
declare font
private readonly Font ZapFont = ZAPFDINGBATS(10, bold: false, color: ColorConstants.BLACK);
private readonly Action<Cell> _cellRight = cell => cell.RemoveBorder().SetTextAlignment(TextAlignment.RIGHT);
Use
document.AddTable(
columns: new float[1]
{
100
},
table => table.SetWidth(document.GetPageEffectiveArea(PageSize).GetWidth())
.SetMargins(0, 0, 0, 0)
.AddCell(model.IsTrue ? "4" : "o", ZapFont, _cellRight );
This worked for me:
pdfStamper.FormFlattening = true;