How justify text using iTextSharp? - c#

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 have one problem-how make that pdf justified? Is any method or something which quickly do that?

Ah, I get it, you mean "justified" instead of "adjusted". I updated your question. It's actually pretty easy. Basically it depends on the type of content that you're adding and whether that content supports this concept in the first place. Assuming that you have basic paragraphs you can set the Alignment property on them before adding them in your main loop:
foreach (var htmlElement in parsedHtmlElements){
//If the current element is a paragraph
if (htmlElement is Paragraph){
//Set its alignment
((Paragraph)htmlElement).Alignment = Element.ALIGN_JUSTIFIED;
}
doc.Add(htmlElement);
}
There's two types of justification, Element.ALIGN_JUSTIFIED and Element.ALIGN_JUSTIFIED_ALL. The second is the same as the first except that it also justifies the last line of text which you may or may not want to do.

Related

System.NullReferenceException: 'Object reference not set to an instance of an object.' page was null

I'm traying to test this method that checks for specific tag footer to show.
here is the function:
public void CheckForOrderOfFooterTags(PdfDocument pdfDoc, out TagTreePointer autoP, out TagTreePointer posBackup, out TagTreeInfo p)
{
// the following logic takes care of changing the order of the footer tags
// so that footers appear in the proper order in the tag tree structure
autoP =pdfDoc.GetTagStructureContext().GetAutoTaggingPointer();
posBackup =new TagTreePointer(autoP);
PagesTag.TryGetValue(PageNumber, out p);
if (p?.TagTreePointer != null)
{
// Make sure that content that will be tagged is placed in tag structure specifically where we need it.
int indexInParentKidsList = p.TagTreePointer.GetIndexInParentKidsList();
autoP.MoveToPointer(p.TagTreePointer).MoveToParent();
// setting new index only works on taggable items
if (p.Tagged)
{
autoP.SetNextNewKidIndex(indexInParentKidsList + 1);
}
}
}
and this is the test:
public void Check_For_Specific_Tag_Footer_To_Show_Successfully_Called()
{
var ir = new TestIllustrationReport().Report;
var reportProperties = new TestDocument().ReportProperties;
var sec = new FooterSection(new ProductContent(ir));
sec.Build();
Dictionary<int, TagTreeInfo> dict = new Dictionary<int, TagTreeInfo>();
reportProperties.FooterTag=dict;
FooterEventHandler footerEvent = new FooterEventHandler(sec, reportProperties);
// Must have write permissions to the path folder
var path = System.IO.Path.GetTempPath();
var fileName = System.IO.Path.ChangeExtension("Test", ".pdf");
var com = System.IO.Path.Combine(path, fileName);
// pdf
PdfWriter writer = new PdfWriter(com);
PdfDocument pdf = new PdfDocument(writer);
Event headerEvent= new PdfDocumentEvent("pdf", pdf);
PdfDocumentEvent docEvent = (PdfDocumentEvent)headerEvent;
iText.Layout.Document document = new iText.Layout.Document(pdf);
pdf.GetCatalog().SetLang(new PdfString("en-US"));
// Header and Paragraph
Paragraph header = new Paragraph(TestData.Header)
.SetTextAlignment(TextAlignment.CENTER)
.SetFontSize(20);
document.Add(header);
pdf.SetTagged();
pdf.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
PdfDocumentInfo info = pdf.GetDocumentInfo();
info.SetTitle("Testing tags");
Paragraph p = new Paragraph();
p.Add("The quick brown ");
PdfPage page = docEvent.GetPage();
// Rectangle and canvas
Rectangle rectangle = new Rectangle(
pdf.GetDefaultPageSize().GetX() + document.GetLeftMargin(),
pdf.GetDefaultPageSize().GetTop() - 80,
page.GetPageSize().GetWidth() - document.GetLeftMargin() - document.GetRightMargin(),
50);
Div canvas = new Div().SetFixedPosition(pdf.GetPageNumber(page), rectangle.GetLeft(), rectangle.GetBottom(), rectangle.GetWidth());
Paragraph pFooter = new Paragraph(TestData.Paragraph);
pFooter.GetAccessibilityProperties().SetRole("H");
canvas.Add(pFooter);
document.Add(canvas);
// Don't close document itself! It would close the PdfDocument!
document.GetRenderer().Close();
var pPointer = new TagTreePointer(pdf);
var pInfo = new TagTreeInfo { Tagged = true };
// Act
footerEvent.CheckForOrderOfFooterTags(pdf, out pPointer, out pPointer, out pInfo);
document.Close();
// Assert
Assert.NotNull(pdf);
}
For this test, I needed to create the pdf, set and build the footer section. I added the header to the pdf and the "footer test", I also set the document to be tagged.
I don't know why I always get the page is null if I'm adding a header and a paragraph to it.

iText7 for .NET barcode

I'd like to create pdf with barcode using Itex7 library.
There is a lot of examples using older version of Itex, or Java, but I can't find solution for Itex7.
(generally new lib has no implementation of createImageWithBarcode method)
My solution could look like as:
string outputPdfFile = #"c:\DEV\pdfFromScratchWithBarCode.pdf";
using (iText.Kernel.Pdf.PdfWriter writer = new iText.Kernel.Pdf.PdfWriter(outputPdfFile))
{
using (iText.Kernel.Pdf.PdfDocument pdf = new iText.Kernel.Pdf.PdfDocument(writer))
{
iText.Layout.Document doc = new iText.Layout.Document(pdf);
doc.Add(new iText.Layout.Element.Paragraph("Title"));
iText.Barcodes.BarcodeInter25 bar = new iText.Barcodes.BarcodeInter25(pdf);
bar.SetCode("00600123456");
//HOW TO ADD barcode TO PDF ??
// ...
}
}
There is similar answer but for older version:
iText for .NET barcode
Thanks for advices.
I found the solution (create pdf, add barcode {type: Code 25 – Non-interleaved 2 of 5} and set valid postion)
using (iText.Kernel.Pdf.PdfWriter writer = new iText.Kernel.Pdf.PdfWriter(outputPdfFile))
{
using (iText.Kernel.Pdf.PdfDocument pdf = new iText.Kernel.Pdf.PdfDocument(writer))
{
iText.Layout.Document doc = new iText.Layout.Document(pdf);
doc.Add(new iText.Layout.Element.Paragraph("Title"));
//barcode
iText.Barcodes.BarcodeInter25 bar = new iText.Barcodes.BarcodeInter25(pdf);
bar.SetCode("0600123456");
iText.Kernel.Pdf.Canvas.PdfCanvas canvas = new iText.Kernel.Pdf.Canvas.PdfCanvas(pdf.GetFirstPage());
//bar.PlaceBarcode(canvas, iText.Kernel.Colors.ColorConstants.BLUE, iText.Kernel.Colors.ColorConstants.GREEN);
iText.Kernel.Pdf.Xobject.PdfFormXObject barcodeFormXObject = bar.CreateFormXObject(iText.Kernel.Colors.ColorConstants.BLACK, iText.Kernel.Colors.ColorConstants.BLACK, pdf);
float scale = 1;
float x = 450;
float y = 700;
canvas.AddXObject(barcodeFormXObject, scale, 0, 0, scale, x, y);
}
}
You can create an image from a PdfFormXObject by doing this:
var barcodeImg = new Image(bar.CreateFormXObject(pdf));
Here is your code including changes that does the trick:
string outputPdfFile = #"c:\DEV\pdfFromScratchWithBarCode.pdf";
using (var writer = new iText.Kernel.Pdf.PdfWriter(outputPdfFile))
{
using (var pdf = new iText.Kernel.Pdf.PdfDocument(writer))
{
var doc = new Document(pdf);
doc.Add(new Paragraph("Title"));
var bar = new BarcodeInter25(pdf);
bar.SetCode("000600123456");
//Here's how to add barcode to PDF with IText7
var barcodeImg = new Image(bar.CreateFormXObject(pdf));
doc.Add(barcodeImg);
}
}

iTextSharp: Setting text on textfield that is on a table cell results in text being too wide and squashed

I think this might be a bug, but if anyone can help I'd appreciate it. I currently have another question open that deals with a similar issue, but I think this question better exemplifies the problem, and more simply too. That being said I don't want to delete the old one in case it increases my wait time. I yield to the mods to decide which question is better.
Here's a sample application that creates a pdf, then a table. It adds a cell to the table and then ties a fieldpositioningevent to the cell event.
using System;
using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace iTextSharpTextBoxInTableCell
{
class Program
{
static void Main(string[] args)
{
// Create a PDF with a TextBox in a table cell
BaseFont bfHelvetica = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, false);
Font helvetica12 = new Font(bfHelvetica, 12, Font.NORMAL, BaseColor.BLACK);
Document doc = new Document(PageSize.LETTER, 18f, 18f, 18f, 18f);
FileStream fs = new FileStream("TextBoxInTableCell.pdf", FileMode.Create);
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
PdfPTable myTable = new PdfPTable(1);
myTable.TotalWidth = 568f;
myTable.LockedWidth = true;
myTable.HorizontalAlignment = 0;
TextField tf = new TextField(writer, new iTextSharp.text.Rectangle(67, 585, 140, 800), "cellTextBox");
tf.Text = "test";
PdfPCell tbCell = new PdfPCell(new Phrase(" ", helvetica12));
iTextSharp.text.pdf.events.FieldPositioningEvents events =
new iTextSharp.text.pdf.events.FieldPositioningEvents(writer, tf.GetTextField());
tbCell.CellEvent = events;
myTable.AddCell(tbCell);
doc.Add(myTable);
doc.Close();
fs.Close();
Process.Start("TextBoxInTableCell.pdf");
Console.WriteLine("End Of Program Execution");
Console.ReadLine();
}
}
}
Here's what this field looks like when it's generated:
As you can see, the text is squashed. I've published the generated pdf here.
I'm definitely seeing what you're seeing and as #mkl said in your other post, the problem comes down to the appearance's BBOX entry not being set to the same size as the field. I can't really find too many examples of FieldPositioningEvents in the wild and the ones that do exist appear to be copy-and-paste's of each other for the most part.
Anyway, if you read the actual code for FieldPositioningEvents you'll see that it can be used for both page events as well as cell events which makes me think it was intended for broader purposes possibly, but that's just a guess on my part.
One solution is to just write your own subclass of IPdfPCellEvent. Below is an example of that that follows the example provided by FieldPositioningEvents however it is specific to TextFields since we're interested in setting the /BBOX entry. It has two constructors, one that works very similar to FieldPositioningEvents that takes a PdfWriter and a TextField and one that just takes the most commonly set properties of a TextFields and actually creates it for you. The CellLayout is part of the interface contract and actually figures out where the annotation should be drawn.
public class SingleCellFieldPositioningEvent : IPdfPCellEvent {
public TextField Field { get; set; }
public PdfWriter Writer { get; set; }
public float Padding { get; set; }
public SingleCellFieldPositioningEvent(PdfWriter writer, TextField field) {
this.Field = field;
this.Writer = writer;
}
public SingleCellFieldPositioningEvent(PdfWriter writer, string fieldName, string text = "", BaseFont font = null, float fontSize = 14 ) {
//The rectangle gets changed later so it doesn't matter what we use
var rect = new iTextSharp.text.Rectangle(1, 1);
//Create the field and set various properties
this.Field = new TextField(writer, rect, fieldName);
this.Field.Text = text;
if (null == font) {
font = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
}
this.Field.Font = font;
this.Field.FontSize = fontSize;
this.Writer = writer;
}
public void CellLayout(PdfPCell cell, iTextSharp.text.Rectangle rect, PdfContentByte[] canvases) {
//Create the field's rectangle based on the current cell and requested padded
var newRect = new PdfRectangle(rect.GetLeft(Padding), rect.GetBottom(Padding), rect.GetRight(Padding), rect.GetTop(Padding));
//Set the appearance's rectangle to the same as the box
Field.Box = newRect.Rectangle;
//Get the raw field
var tf = this.Field.GetTextField();
//Change the field's rectangle
tf.Put(PdfName.RECT, newRect);
//Add the annotation to the writer
Writer.AddAnnotation(tf);
}
}
You can use this in two different ways. Either manually create a field and set various properties:
//The rectangle is actually changed in the cell event so it doesn't matter what we use
TextField tf = new TextField(writer, new iTextSharp.text.Rectangle(1, 1), "cellTextBox");
tf.Text = "test";
tf.Font = bfHelvetica;
tf.FontSize = 14;
PdfPCell tbCell = new PdfPCell(new Phrase(" ", helvetica12));
tbCell.CellEvent = new SingleCellFieldPositioningEvent(writer, tf);
Or just pass the properties in:
PdfPCell tbCell = new PdfPCell(new Phrase(" ", helvetica12));
tbCell.CellEvent = new SingleCellFieldPositioningEvent(writer, "cellTextBox", "test", bfHelvetica, 14);
myTable.AddCell(tbCell);

HTMLWorker itextSharp image src

I am trying to use HTMLWorker using the following:
public static string toWorks(string s)
{
string fontpath = System.Web.HttpContext.Current.Server.MapPath("~/Content/");
BaseFont bf = BaseFont.CreateFont(fontpath + "ARIALUNI.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
var f = new Font(bf, 10, Font.NORMAL);
// var p = new Paragraph { Alignment = Element.ALIGN_LEFT, Font = f };
var styles = new StyleSheet();
styles.LoadTagStyle(HtmlTags.SPAN, HtmlTags.FONTSIZE, "10");
styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.ENCODING, BaseFont.IDENTITY_H);
using (var sr = new StringReader(s))
{
List<IElement> list = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(sr, styles);
// var elements = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(sr, styles);
foreach (var e in list)
{
list.Add(e);
}
return list.ToString();
}
return null;
}
It converts:
src="/Content/UserFiles/635380078478327671/Images/test.png
To:
C:\Content\UserFiles\635380078478327671\Images\test.png
Any suggestion.
Please compare the following two examples:
HtmlMovies1
HtmlMovies2
If you use the first example to render an HTML file with images, you probably won't succeed. The second example introduces an ImageProvider implementation.
In the getImage() method of the ImageProvider interface, you get information about the path to an image. It is up to you to interpret this path. For instance: if the path is /Content/UserFiles/635380078478327671/Images/test.png, you can create an Image object by loading the bytes from that path, possibly after applying some minor changes to the path.
If you don't create an ImageProvider class, iText will do a single guess to find the path. In your case, that guess is wrong.
You can find the C# equivalent of the examples here: http://tinyurl.com/itextsharpIIA2C09

How to use DrawTable using dbAutoTrack

I am using dbAutoTrack for generate PDF in that I have to add Table but I get the Exception like object references is not set to an instance of object
Below is my code
Table t=new Table();
Row row=new Row(t);
row.Cells.Add("ABC");
t.Rows.Add(row);
_pdfGraphics.DrawTable(100,200, t);
where _pdfGraphics is object of PDFGraphics.
Thanks in Advances
Most probably you have message like: "Not enough columns in this row to have a column span of 1." And you needed just to add them.
Workable sample:
//Initialize a new PDF Document
Document _document = new Document();
_document.Title = "Аpitron Sample";
_document.Author = "StanlyF";
_document.Creator = "АPItron LTD.";
Page page = null;
PDFGraphics graphics = null;
Table _table = new Table();
_table.Columns.Add(30);
Row row = new Row(_table);
row.Height = 25;
row.Cells.Add("ABC");
_table.Rows.Add(row);
while (_table != null)
{
//Initialize new page with default PageSize A4
page = new Page(PageSize.A4);
//Add page to document
_document.Pages.Add(page);
//Get the PDFGraphics object for drawing to the page.
graphics = page.Graphics;
_table = graphics.DrawTable(100,200, _table);
}
using(FileStream _fs = new FileStream("Table_Sample.pdf", System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
//Generate PDF to the stream
_document.Generate(_fs);
Process.Start("Table_Sample.pdf");
}
The accepted answer didn't work for me and I was still getting null reference exceptions. It turns out that the rows need to be added with a TableStyle otherwise the cells, for whatever reason, won't be generated:
StandardFonts standardfont = StandardFonts.Helvetica;
PDFFont fontSmall_reg = new PDFFont(standardfont, FontStyle.Regular);
TableStyle ts = new TableStyle(fontSmall_reg, 12, nullBorder);
Table data = new Table(ts);
data.Columns.Add(100);
data.Columns.Add(100);
Row r = new Row(data, ts);
r.Height = 25;
r.Cells.Add("Row 1 Col1");
data.add(r)
r.Cells.Add("Row 1 Col2");

Categories

Resources