iTextSharp Mixed Alignments in Same Object - c#

I want to have a function that returns one object, with this object containing two paragraph with different alignments. This is easy to do manually by making them separate paragraphs and adding them to the pdf one at a time, but I would like my function to return it as a whole object to be added to a pdf. Is this possible? As an example of what I want:
someTextHere
someMoreTextHere
But as one object which I can then add to a pdf.

I have created a small standalone iText 7 example that creates the following output:
Th PDF file shown in the screen shot was created like this:
public void createPdf(String dest) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Div div = new Div()
.add(new Paragraph("Left").setTextAlignment(TextAlignment.LEFT))
.add(new Paragraph("Right").setTextAlignment(TextAlignment.RIGHT))
.setBackgroundColor(ColorConstants.GRAY)
.setWidth(200);
document.add(div);
document.close();
}
As you can see, I created a Div element (similar to a <div> tag in HTML) to which I added two Paragraph objects with a different text alignment. That seems to be exactly what you need.
I am not a C# developer, hence I provide the code in Java. However, if you're proficient in C#, you shouldn't have any problem porting it from Java to C# (it's just a matter of changing lowercases into uppercases, such as changing add() into Add()).
Note that this is iText 7 code; if you're still using iText 5, you should consider upgrading to the latest iText version since iText 5 has gone into maintenance mode a while ago. Maintenance mode means that development on that version has stopped; it's no longer supported for users who aren't a customer.

Related

iTextSharp upgrade to iText7 .NET

This is my iText5 code that does what I have previously required done with HTML snippets;
//GetFieldPositions returns an array of field positions if you are using 5.0 or greater
rectangle = pdfStamper.AcroFields.GetFieldPositions(field.Key)[0].position;
//tell itextSharp to overlay this content
PdfContentByte contentBtye = pdfStamper.GetOverContent(1);
var elements = XMLWorkerHelper.ParseToElementList(pdfPlaceHolderData[key].ToString(), null);
ColumnText ct = new ColumnText(contentBtye);
ct.SetSimpleColumn(rectangle.Left, rectangle.Bottom, rectangle.Right, rectangle.Top);
ct.Add(elements);
ct.Go(false);
pdfFormFields.SetField(field.Key, string.Empty);
I am struggling to see how to convert this to work in iText7 .NET.
XMLWorkerHelper.ParseToElementList returns 'ElementList' which inherits 'List'. 'IElement' is structured as follows;
The iText7 Html2Pdf call to HtmlConverter.ConvertToElements(html) returns an 'IList'. However 'IElement' is now structured as follows;
I was hoping that I could of just used this result but obviously my call to 'ct.Add(elements);' in the above code chokes because of the different IElement structure.
I know I am trying to cut corners here (I have no choice at the moment); is there a relatively easy way to convert the iText7 IElement to the iTextSharp IElement that will retain my nicely parsed HTML with images?
How can I replace an acro form field content with parsed HTML instead? This would preferably be in iTextSharp 5, but I suppose would be even better using the latest version?
I currently have a solution working happily with iTextSharp 5 that allows PDF templates to populated dynamically. I have hit a problem using the XMLWorkerHelper.ParseToElementList as it does not seem to support parsing inline images.
I have found that iText7 for .net has an extension called html2pdf that has a method called HtmlConverter.ConvertToElements that does perfectly parse HTML with inline images however the result is not compatible with my iTextSharp 5 implementation and I am struggling in trying to convert it.

How to fill forms like this using iText for .NET

Trying to fill name and address on each boxes using
cb.SetTextMatrix(x, y);// x and y positions .
cb.ShowText("data");
But fails to do so .
the problem
The code you are using isn't entirely incorrect, but it has several flaws. For starters: you don't know the value of the x and y parameters, and that's kind of crucial if you want the text to be in the correct position.
Also: you are writing PDF syntax directly into the content stream. In your snippet, you forgot to create the text object (with cb.BeginText() and cb.EndText()). If you are new at PDF, you shouldn't try writing PDF syntax directly into the content stream unless you have a solid understanding of ISO-32000-1. Have you ever read ISO-32000-1? If not, then why are you using low-level operations? That doesn't make much sense, does it? There are helper classes such as ColumnText to add content at absolute positions.
Looking at the screen shot you shared, I see that some fields require "Comb" functionality. This functionality makes sure that each small box contains exactly one glyph (if you don't know what a glyph is, think of it as the visual representation of a character).
If you want to make it easy on yourself, you should test if the form is interactive first. Answer this question:
Does the form contain AcroFields?
If the answer is "Yes", fill out the form using the AcroFields object. You can find out which field names to use by following the instructions in the answer to this question: How do I enumerate all the fields in a PDF file in ITextSharp ?
If the answer is "No", open the file in Adobe Acrobat, and manually add fields. Define the fields as Comb fields so that each box contains each glyph. To get a nice-looking result, select a monospaced font such as Courier (using a proportional font will probably give you an uglier result). This operation adds AcroForm fields.
Once you have an interactive form with AcroFields (assuming you have defined them correctly), filling out the form is as easy as this in iText 5:
PdfReader reader = new PdfReader(template);
PdfStamper stamper = new PdfStamper(reader,
new FileStream(newFile, FileMode.Create));
AcroFields form = stamper.AcroFields;
form.SetField(key1, value1);
form.SetField(key2, value2);
form.SetField(key3, value3);
...
stamper.Close();
See How to create and fill out a PDF form
However, since you are new at all of this, I recommend that you use iText 7 as described in the jump-start tutorial:
PdfDocument pdf = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
IDictionary<String, PdfFormField> fields = form.GetFormFields();
PdfFormField toSet;
fields.TryGetValue(key1, out toSet);
toSet.SetValue(value1);
fields.TryGetValue(key2, out toSet);
toSet.SetValue(value2);
...
pdf.Close();
If you want to remove the interactivity after filling out the form, you need to flatten the fields. This is also documented on the official web site.

How can I parse through a table in a pdf file?

I have a custom table with name, firstname, place of birth and place of living in a PDF file which I want to parse through in C#. One of the simplest way of doing it would be:
using (PdfLoadedDocument document = new PdfLoadedDocument("foobar"))
{
for (var i = 0; i < document.Pages.Count; i++)
{
Console.WriteLine($"============ PAGE NO. {i+1} ============");
Console.WriteLine(document.Pages[i].ExtractText());
}
}
But the problem is the output:
============ PAGE NO. 38 ============
John L.SmithSan Francisco5400 Baden
There's no way I can seperate this with a regex so I need a way to parse through each column of each row in order to get all the values of the customers separated. How can I parse through a table in a pdf file with syncfusion?
You will need a methods that returns you the coordinate of each character found in the pdf. Then you have some math to do (basically to compute the distance between characters) in order to know if the character is part of a word and where the word itself is located along the x-axe. It requires quite a lot of work and efforts and I didn't find such a method in syncfusion documentation.
I wrote a class which do what you want but this is for java project:
PDFLayoutTextStripper (upon PDFBox)
Syncfusion control extracting the text from PDF document based on the structure of content present in the PDF document. So, based on current implementation of Syncfusion control we cannot recognize the rows and columns present in the table of the PDF document.
Also, it is not possible to extract the text in correct order as same as the PDF document displayed using Syncfusion control since the content present in the PDF document follows fixed layout.
But we can populate the table of the PDF document in Excel using Tabula (Open source library). I have modified the Tabula java (Open Source) to achieve layout based text extraction from the PDF document based on your requirement.
Please find the sample for this implementation in below link:
http://www.syncfusion.com/downloads/support/directtrac/171585/ze/TextExtractionSample649531336
Kindly ensure the following things before executing the sample:
Install Java Runtime Environment (JRE) from the below link.
http://www.oracle.com/technetwork/java/javase/downloads/
Restart your machine.
Execute the above sample.
Try this and check whether it meets your requirement.

OpenXML: Anyway to see if a Word Document fits one page

While I doubt it, if I open up a word document using OpenXML sdk in C# and add some info, is there any way for me to see if it still fits one page?
If it doesn't I wan't to reduce font size on specific items I added until it fits.
I could write this algorithm if I had the current size in relation to page size with margins and all that.
I ran across this example on another site, don't know if it'll work in your case, as it requires the Office PIA...
var app = new Word.Application();
var doc = app.Documents.Open("path/to/file");
doc.Repaginate()
var pageNumber = doc.BuiltInDocumentProperties("Number of Pages").Value as int;

Print Adobe Illustrator documents

I have one file called test.ai and I need to print it several times, but changing the text inside it each time.
Added the illustrator reference to the project and it is already changing the text inside the image, my problem is to stack up several of these documents and send them to a printer or to the printing dialog.
Here is the code to open the file
//open AI, init
Illustrator.Application illuApp = new Illustrator.Application();
// open doc
Illustrator.Document illuDoc = illuApp.Open("C:\\myai.ai", Illustrator.AiDocumentColorSpace.aiDocumentRGBColor, null);
there is this illuDoc.PrintOut function, it takes one option object as parameter, but I can't seem to find the documentation about it. And don't know if it could help in my situation.
How could I achieve this?
Thanks!
Jonathan
According to the documentation I find here (I assume this is the library that you're using?), the PrintOut function takes PrintOptions as an argument.
PrintOptions collects all information about all printing options including flattening, color management, coordinates, fonts, and paper. Used as an argument to the PrintOut method. (page 184)
You should be able to set up a loop in your code with the number of iterations equal to the number of documents that you want printed, and in the body of that loop, make the change to the text of the document and call the PrintOut function for that document with the appropriate PrintOptions parameters.
Your best bet is to avoid any AI references for direct printing. The storage format for an AI file is nearly identical to a PDF (make a copy and change the extension from .ai to .pdf and be amazed). This opens the door to using any pdf printing method for your Illustrator file.

Categories

Resources