ITextSharp v5.5.13.0 XMLWorker Turkish character problem - itext

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;
}

Related

Response a new word from a template without copy

`
System.IO.File.Copy(wordFullPath, wordFullPathCopy, true);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(wordFullPathCopy, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
docText = docText.Replace("[$1-1-1$]", "TEST1");
docText = docText.Replace("[$1-1-2$]", "TEST2");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
}
byte[] byteArray = File.ReadAllBytes(wordFullPathCopy);
System.IO.File.Delete(wordFullPathCopy);
Page.Response.Clear();
Page.Response.AppendHeader("Content-Disposition", "attachment; filename=DocxDllTest.docx");
Page.Response.ContentType = "application/octet-stream";
Page.Response.BinaryWrite(byteArray);
Page.Response.OutputStream.Flush();
Page.Response.OutputStream.Close();
Page.Response.Flush();
Page.Response.End();`
Hi~I have a docX template(Of course,It must read only!!).
Now I make a copy and use WordprocessingDocument to replace text.
It worked fine.
But now,I want to not make a copy.
Just replace text and save to memorystream then Response to user.
Is it possible? and How??
Thx!!
byte[] wordByteArray = null;
string wordFullPath = FileHelper.FileFromFileDir("ATT1.docx"); //Template
wordByteArray = File.ReadAllBytes(wordFullPath);
using (MemoryStream ms = new MemoryStream())
{
string docText = null;
ms.Write(wordByteArray, 0, (int)wordByteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(ms, true))
{
using (StreamReader sr = new StreamReader(doc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
docText = docText.Replace("[$1-1-1$]", "TEST1");
docText = docText.Replace("[$1-1-2$]", "TEST2");
}
byte[] docTextByteArray = Encoding.UTF8.GetBytes(docText);
MemoryStream memDocText = new MemoryStream(docTextByteArray);
doc.MainDocumentPart.FeedData(memDocText);
}
Page.Response.Clear();
Page.Response.AppendHeader("Content-Disposition", "attachment; filename=DocxDllTest.docx");
Page.Response.ContentType = "application/octet-stream";
Page.Response.BinaryWrite(ms.ToArray());
Page.Response.OutputStream.Flush();
Page.Response.OutputStream.Close();
Page.Response.Flush();
Page.Response.End();
OK!!It work!!
Thank stackOverflow's users!!

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.

Duplicate Fields using itextsharp

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();

iTextSharp line separator disappears with PdfPageEventHelper

I'm producing PDF reports using the iTextSharp library. I have a paragraph as title with a line underneath.
When I add an PdfPageEventHelper class as PageEventListener to my writer which handles the background and page numbering on each page, the line disappears. I think it's about the alignment of the background and the line so the line is behind the background but I can't seem to arrange it in front.
Document code:
using (Document doc = new Document())
{
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=IVIPS_report.pdf");
doc.SetPageSize(PageSize.A4.Rotate());
doc.SetMargins(36f, 36f, 36f, 70f);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
bckgr = Image.GetInstance(Request.MapPath(PDF_BACKGROUND_LANDSCAPE_PATH));
bckgr.Alignment = Image.UNDERLYING;
bckgr.SetAbsolutePosition(0, 0);
bckgr.ScaleToFit(doc.PageSize);
PdfWriter writer = PdfWriter.GetInstance(doc, Response.OutputStream);
MyPdfPageEventHelpPageNo PdfPageEvent = new MyPdfPageEventHelpPageNo();
writer.PageEvent = PdfPageEvent;
doc.Open();
Font title = new Font(Font.FontFamily.HELVETICA, 16f, Font.BOLD, BaseColor.DARK_GRAY);
Paragraph p = new Paragraph("Overzicht chauffeurs", title);
p.Alignment = Element.ALIGN_LEFT;
LineSeparator line = new LineSeparator(1f, 100f, BaseColor.DARK_GRAY, Element.ALIGN_CENTER, -27f);
doc.Add(p);
doc.Add(line);
}
PdfPageEvent code:
public class MyPdfPageEventHelpPageNo : iTextSharp.text.pdf.PdfPageEventHelper
{
public override void OnEndPage(PdfWriter writer, Document document)
{
document.Add(bckgr);
Font fFooter = new Font(Font.FontFamily.HELVETICA, 9f, Font.NORMAL, BaseColor.GRAY);
Rectangle page = document.PageSize;
PdfPTable pageFooter = new PdfPTable(1);
pageFooter.TotalWidth = page.Width;
Phrase pagenr = new Phrase("Gegenereerd op " + DateTime.Now.ToString("dd/MM/yyyy") + " - Pagina " + document.PageNumber, fFooter);
PdfPCell c = new PdfPCell(pagenr);
c.Border = Rectangle.NO_BORDER;
c.VerticalAlignment = Element.ALIGN_BOTTOM;
c.HorizontalAlignment = Element.ALIGN_CENTER;
pageFooter.AddCell(c);
pageFooter.WriteSelectedRows(0, -1, 0, 25, writer.DirectContent);
}
}

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);