Duplicate Fields using itextsharp - itext

I have this code to create TextFields
public void MssCreateTextField(byte[] ssPdf, RCRectangleRecord ssRectangle, string ssName, int ssFontSize, string ssValue, int ssPage, out byte[] ssPdfOut, bool ssIsMultiline) {
PdfReader reader = new PdfReader(ssPdf);
ssPdfOut = null;
var output = new MemoryStream();
var stamper = new PdfStamper(reader, output);
/*TextField tField = new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)ssRectangle.ssSTRectangle.ssllx, (float)ssRectangle.ssSTRectangle.sslly, (float)ssRectangle.ssSTRectangle.ssurx, (float)ssRectangle.ssSTRectangle.ssury), ssName);
if (ssValue!="")
tField.Text = ssValue;
if (ssIsMultiline)
tField.Options = TextField.MULTILINE;
tField.FontSize = ssFontSize;*/
PdfFormField tField = PdfFormField.CreateTextField(stamper.Writer, ssIsMultiline, false, 50);
tField.FieldName = ssName;
tField.SetWidget(new iTextSharp.text.Rectangle((float)ssRectangle.ssSTRectangle.ssllx, (float)ssRectangle.ssSTRectangle.sslly, (float)ssRectangle.ssSTRectangle.ssurx, (float)ssRectangle.ssSTRectangle.ssury), PdfAnnotation.HIGHLIGHT_TOGGLE);
stamper.FormFlattening = false;
stamper.AddAnnotation(tField, ssPage);
stamper.Close();
reader.Close();
ssPdfOut = output.ToArray();
}
As you can see i have some code commented as an alternative but the two different ways are producing the same result.
What i am trying to achieve is create two textfields with the same name to when editing one it edits the others two. This two codes do that (in the browsers and pdfescape site) excepting in the adobe acrobat reader. In the acrobat reader i get just the first field visible and the others hidden i dont know why...

If you want to add two text field visualizations which represent the same content, you have to add them as two widgets of the same field and not two distinct fields, e.g. like this:
public void CreateDoubleTextField(byte[] ssPdf, Rectangle ssRectangle1, Rectangle ssRectangle2, string ssName, int ssFontSize, string ssValue, int ssPage, out byte[] ssPdfOut, bool ssIsMultiline)
{
PdfReader reader = new PdfReader(ssPdf);
ssPdfOut = null;
var output = new MemoryStream();
var stamper = new PdfStamper(reader, output);
PdfFormField tField = PdfFormField.CreateTextField(stamper.Writer, ssIsMultiline, false, 50);
tField.FieldName = ssName;
PdfFormField widget1 = PdfFormField.CreateEmpty(stamper.Writer);
widget1.SetWidget(ssRectangle1, PdfAnnotation.HIGHLIGHT_TOGGLE);
PdfFormField widget2 = PdfFormField.CreateEmpty(stamper.Writer);
widget2.SetWidget(ssRectangle2, PdfAnnotation.HIGHLIGHT_TOGGLE);
tField.AddKid(widget1);
tField.AddKid(widget2);
stamper.FormFlattening = false;
stamper.AddAnnotation(tField, ssPage);
stamper.Close();
reader.Close();
ssPdfOut = output.ToArray();
}
(As I don't have that RCRectangleRecord, I use the iTextSharp Rectangle class as argument.)
This gives you two field visualizations in Adobe Acrobat Reader; after editing one of them and switching focus (e.g. clicking somewhere outside that visualization), the other visualization duplicates the content.

Now i have this and i can create two fields when the list has more than one Rectangle but for some reason i dont know how the two fields appears without the name!!
PdfReader reader = new PdfReader(ssPdf);
ssPdfOut = null;
var output = new MemoryStream();
var stamper = new PdfStamper(reader, output);
TextField tField;
if (ssRectangle.Count==1){
tField= new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)ssRectangle[0].ssSTRectangle.ssllx, (float)ssRectangle[0].ssSTRectangle.sslly, (float)ssRectangle[0].ssSTRectangle.ssurx, (float)ssRectangle[0].ssSTRectangle.ssury), ssName);
if (ssValue!="")
tField.Text = ssValue;
if (ssIsMultiline)
tField.Options = TextField.MULTILINE;
tField.FontSize = ssFontSize;
tField.FieldName = ssName;
stamper.AddAnnotation(tField.GetTextField(), ssPage);
}
else
{
PdfFormField PtField = PdfFormField.CreateTextField(stamper.Writer, ssIsMultiline, false, 250);
PtField.Name=ssName;
foreach (RCRectangleRecord item in ssRectangle)
{
/*
tField=new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)ssRectangle[0].ssSTRectangle.ssllx, (float)ssRectangle[0].ssSTRectangle.sslly, (float)ssRectangle[0].ssSTRectangle.ssurx, (float)ssRectangle[0].ssSTRectangle.ssury), ssName);
tField.FieldName = ssName;
PtField.AddKid(tField.GetTextField());*/
PdfFormField widget = PdfFormField.CreateEmpty(stamper.Writer);
widget.SetWidget(new Rectangle((float)item.ssSTRectangle.ssllx, (float)item.ssSTRectangle.sslly, (float)item.ssSTRectangle.ssurx, (float)item.ssSTRectangle.ssury), PdfAnnotation.HIGHLIGHT_TOGGLE);
widget.Name = ssName;
PtField.AddKid(widget);
}
stamper.AddAnnotation(PtField, ssPage);
}
stamper.FormFlattening = false;
stamper.Close();
reader.Close();
ssPdfOut = output.ToArray();

Related

ITextSharp v5.5.13.0 XMLWorker Turkish character problem

I used iTextSharp and all Turkish character disappeared.
Also html inline css attributes work on table element but not working on div element.
I tried lots of encoding convert sample code but not found any results.
My sample code:
public static byte[] HtmlToPdfItextSharp(string HTMLCONTENTSTRING, List<string> cssFiles = null)
{
using (var ms = new MemoryStream())
{
Document pdfDoc = new Document(PageSize.A4.Rotate(), 10, 10, 10, 10);
BaseFont STF_Helvetica_Turkish = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, "CP1254", BaseFont.NOT_EMBEDDED);
Font fontNormal = new Font(STF_Helvetica_Turkish, 12, Font.NORMAL, BaseColor.BLACK);
string fontPath = Path.Combine(Path.Combine(Server.MapPath("~/App_Data/Pdf/arial.ttf")));
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.UseUnicode = true;
fontProvider.Register(fontPath);
CssAppliers ca = new CssAppliersImpl(fontProvider);
var pdfWriter = PdfWriter.GetInstance(pdfDoc, ms);
pdfDoc.Open();
pdfWriter.DirectContent.SetFontAndSize(STF_Helvetica_Turkish, 12);
pdfWriter.CloseStream = false;
var htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssFiles.ForEach(e => cssResolver.AddCssFile(e, true));
var pp = new PdfWriterPipeline(pdfDoc, pdfWriter);
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, pp));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser parser = new XMLParser(worker);
parser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(HTMLCONTENTSTRING)));
pdfDoc.Close();
return ms.GetBuffer();
}
}
I updated my code and add stylesheet file (with font familiy:arial;) and i solved character
but it takes too long time
My new updated function like:
public static byte[] HtmlToPdfItextSharp(string HTMLCONTENTSTRING, List<string> cssFiles = null)
{
using (var ms= new MemoryStream())
{
Document pdfDoc = new Document(PageSize.A4.Rotate(), 10, 10, 7, 10);
var pdfWriter = PdfWriter.GetInstance(pdfDoc, ms);
pdfWriter.CloseStream = false;
pdfDoc.Open();
var htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssFiles.ForEach(e => cssResolver.AddCssFile(e, true));
var pp = new PdfWriterPipeline(pdfDoc, pdfWriter);
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, pp));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser parser = new XMLParser(worker);
parser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(pHtmlIcerik)));
pdfDoc.Close();
return ms.ToArray();
}
}
Css code :
body {
font-family:Arial;
}
table{
font-family:Arial;
}
td{
font-family:Arial;
}

Set the iText 7 page size based on the HTML content

I have the following Java program to create an iText PDF:
//Create the PDF file
public int CreatePDF(String[] pSrc,
String pDest)
throws IOException
{
//Initialize
ConverterProperties vProperties = new ConverterProperties();
//Adding the fonts
FontProvider vfontProvider = new DefaultFontProvider(false, false, false);
for (String font : FONTS)
{
FontProgram vfontProgram = FontProgramFactory.createFont(font);
vfontProvider.addFont(vfontProgram);
}
vProperties.setFontProvider(vfontProvider);
PdfWriter vWriter = new PdfWriter(pDest, new WriterProperties().setCompressionLevel(9));
PdfDocument vPDF = new PdfDocument(vWriter);
PdfMerger vMerger = new PdfMerger(vPDF);
//Convert to PDF
for (String vHTML : pSrc)
{
ByteArrayOutputStream vArrByteAOS = new ByteArrayOutputStream();
PdfDocument vDoc = new PdfDocument(new PdfWriter(vArrByteAOS, new WriterProperties().setCompressionLevel(9)));
vDoc.setDefaultPageSize(new PageSize(735, 1080));
HtmlConverter.convertToPdf(vHTML, vDoc, vProperties);
vDoc = new PdfDocument(new PdfReader(new ByteArrayInputStream(vArrByteAOS.toByteArray())));
vMerger.merge(vDoc, 1, vDoc.getNumberOfPages());
vDoc.close();
}
vPDF.close();
return 0;
}
How can I set the Page Height (now hardcoded to 1080) based on the size of the HTML content (pSrc) in order to ensure that it fits to one page.

iTextSharp PdfStamper.PartialFormFlattening flattening only some, not all, of the fields

The code below is correctly assigning the value "foo" to the named field, but the field is not being "flattened". I must be neglecting a step, but I don't know what it is. Please advise. Thanks.
public byte[] FlattenSpecifiedFormFields(byte[] b, List<string> fieldNames2Flatten)
{
PdfReader reader = new PdfReader(b);
using (var ms = new MemoryStream())
{
var stamper = new iTextSharp.text.pdf.PdfStamper(reader, ms);
foreach (string name in fieldNames2Flatten)
{
stamper.AcroFields.SetField(name, "foo");
stamper.PartialFormFlattening(name);
}
stamper.Close();
return ms.ToArray();
};
}
Even when partially flattening a form, the PdfStamper FormFlattening property must be set to true. I.e.:
var stamper = new PdfStamper(reader, ms);
stamper.FormFlattening = true;
foreach (string name in fieldNames2Flatten)
{
stamper.AcroFields.SetField(name, "foo");
stamper.PartialFormFlattening(name);
}

I cannot write into specific location in pdf

Trying to manipulate pdf with using pdfstamper I don't know what's wrong in the code it doesn't print textfield in output file. Thanks in advance
PdfReader reader = new PdfReader("Players.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(Result));
AcroFields form = stamper.getAcroFields(); // using acro fields to fill out the pdf
form.setGenerateAppearances(true);
rs = statement.executeQuery("SELECT * from Players");
while ( rs.next() ) {
String Country = null;
Country = rs.getString("CName");
System.out.println(Country);
if (rs != null)
Country = rs.getString("CName");
form.setField("Country",Country);
}
stamper.setFormFlattening(true);
stamper.close();
connection.close();

How change encoding in MemoryStream (use that to create pdf)

Have piece of code like below:
var workStream = new MemoryStream();
var doc = new Document(PageSize.LETTER, 10, 10, 42, 35);
PdfWriter.GetInstance(doc, workStream).CloseStream = false;
doc.Open();
var builder = new StringBuilder();
builder.Append("MY LONG HTML TEXT");
var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(builder.ToString()), null);
foreach (var htmlElement in parsedHtmlElements)
doc.Add(htmlElement);
doc.Close();
byte[] byteInfo = workStream.ToArray();
workStream.Write(byteInfo, 0, byteInfo.Length);
workStream.Position = 0;
return new FileStreamResult(workStream, "application/pdf")
And problem - i want to have some polish letters in my pdf (like "ą","ę" etc.)
How to do that?
You need to register a font and then specify the encoding by using stylesheets:
FontFactory.Register("c:\\windows\\fonts\\tahoma.ttf");
StyleSheet styles = new StyleSheet();
styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.FONTFAMILY, "tahoma");
styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.ENCODING, "Identity-H");
var html = #"data";
var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(html), styles);