PDF Generation Using CSS and JAVA - java

I am generating a PDF comprised of multiple tables and I want to know if there is a certain way by which I can get to know if the table size will exceed the PDF page size or not. I am using the information to decide wether I will generate the PDF in portrait or landscape mode. Would it be possible to get this size?

know if the table size will exceed the PDF page size
The table size is determined from your XHTML Table Content (rows, columns, headers, footers, etc), plus your CSS doc(s) (width, height and border properties).
The rendering engine (ITextRenderer) only knows your table size, and whether it will fit within a page after it's applied CSS, as part of the process of converting XHTML to rendered output.
So, if you were to query ITextRenderer for this information, you would need to:
Create an ITextRenderer instance, pass your Document in via renderer.setDocument(), and then apply the CSS via renderer.layout(), causing all of the layout calculations to occur based upon the original page orientation
Query somehow to determine if the table fits on the page
If it doesn't, switch between portrait/landscape. But this means changing to a new CSS, setup for a different page shape:
Pick a new CSS, appropriate for the new page orientation and set it within your document
Create a new ITextRenderer instance, pass your Document in via renderer.setDocument(), and then apply the CSS via renderer.layout(), causing all of the layout calculations to occur based upon the new page orientation.
Create PDF output via renderer.createPDF().
Problems:
This is inefficient and inelegant processing.
This is doing things the wrong way around. Controlling page layout should be part of the design process, and should be reflected in (a) the content generated (XHTML) and (b) the formatting (CSS). If that's done correctly, there should be no need to do render-time magic to reformat the entire page.
At step (2), there's no simple query interface that will simply tell you if your table fits within a page. Instead, you have to query the formatted output blocks, and try to work out for yourself where your table is and whether it fits in a page. E.g.:
BlockBox root = renderer.getRootBox();
List pageList = root.getLayer().getPages()
PageBox page = (PageBox)pageList.get(2);
List childBoxList = page.getChildren();
Box childBox = (Box)childBoxList.get(0);
// etc... until you locate your table
At step (4), ITextRenderer expects your CSS to be linked from within your XHTML document. That means you first need to modify your XHTML source, then you need to resubmit it to ITextRenderer.
Suggested Alternative:
Do a wireframe/sketch design with 2 scenarios - one for portrait & one for landscape
Determine the size of elements/rows/columns under the 2 scenarios
Determine the condition logic under which you would use each scenario, portrait v landscape. E.g. if I the number of rows is X and the number of columns is Y - then use landscape, ...
Now create the two CSS files
Now, when you generate your XHTML, use the condition logic to link to the correct CSS

Related

How to inject images into a Word template via docx4j without getting them resized

My program injects text and pictures into a Word template. This works great via content control data binding (thanks to docx4j and Content-Control-Toolkit).
My problem is, that images get resized after injection. What I actually want, is the behavoir that Jason decribed here: http://www.docx4java.org/forums/data-binding-java-f16/picture-content-control-size-t634.html
The current behaviour is to just let it be whatever its natural size is (at a given dpi), unless that is greater than page width, in which case it is scaled down.
According to that post, the behavoir of docx4j has been changed so that the pictures always fit the size of the content control with respect to the ratio.
Is it possible to get the "old" behavoir back? Do I have to do that on my own, or is the switch, that Jason wrote about, already implemented?
As the answer to How to force Docx4j to refresh a replaced image file states, the size of a picture is stored in the main document part. At the moment, I only use XPath to set content in the custom XML part. If there is any possibility to get what I need without touching the documents XML directly, I would really prefer that. A macro to set the size after opening the document in Word is no option for me.
The first thing to be aware of is that these days we prefer to have a picture in a rich text content control, as opposed to a picture content control.
This is because Word limits your ability to "float" a picture content control.
The handling for this is triggered by w:tag containing 'od:Handler=picture': datastorage/bind.xslt#L165
The basic behaviour is that if the w:sdtContent contains an existing w:drawing/wp:inline/a:graphic then reuse it, so any formatting thus configured is used.
But for a "legacy" picture content control which doesn't contain a:blip (when would this be?), xpathInjectImage is invoked with wp:extent passed in (see bind.xslt#L240).
At line 1143, if (cxl==0 || cyl==0) // Let BPAI work out size
So if you want the image at its natural size, you could try removing the when clause at bind.xslt#L212
By the way, we can also bind escaped XHTML. But there, we make an effort to fit any image not just to the page width, but if in a table cell, to that as well.

how to avoid blank page at the end of pdf report in BIRT?

I am using current BIRT version that is 4.5. I have two master pages in my report. I have huge data to display on a report so i have set some data to display on one master page and the remaining on another master page due to some reason. The problem is when there is no data to display on one of the master page it is rendering a blank page with header and footer of that master page which i want to avoid. In my pdf report how can i avoid this blank page?
Hi, all are pointing to hide tables or other components but my requirement here is, i need to hide the page itself. I dont think there is visibility option for page. even if it is there it is not so useful. Kindly understand that i dont want to display the page itself not only the components in it.so can i expect any help now?
I guess you added the tables directly on the masterpage?
That's not how it works. BIRT will render the (master)page and maybe hide the elements on them (for example a table that has no data. You can do this by setting the visibility property). The problem with this approach is that the Masterpage cannot be 'unrenderred'.
The proper way to fix this, is to add each element on the normal layout. In the properties for each table, grid, etc. you can set the pagebreak properties. Here you can select the Masterpage you want to use. If an element does not need to be rendered (by visibility settings), it wont trigger a 'blank' masterpage.
Hope that helps.

how to extract PDF watermark content using iText apis

I was going through the itext api docs & I was able create a pdf with a watermark image or text but did not find a method to get/extract watermark content from pdf.
So I have a pdf document containing watermarked text/image & I want to extract that text or img and validate which I am not able to do.
How to extract watermark content using iText apis? Or is there any other way to validate watermark content?
By validate I mean if I have an existing pdf/image with some watermarked text [as done in 2nd link in above ref], I want to check whether it has expected text/image.
References:
http://itextpdf.com/themes/keyword.php?id=226
http://www.java-connect.com/itext/add-watermark-in-PDF-document-using-java-iText-library.html
How to extract watermark content using iText apis? Or is there any other way to validate watermark content?
Extracting watermark content?
There is nothing special about watermarks in PDFs in contrast to regular page content. They merely
appear pretty early in the content stream and other content later in the stream, therefore, is drawn above it; or they
appear pretty late in the content stream but have some kind of transparency applied.
Actually there is another type of watermarks which is special, the so-called Watermark Annotations. As these annotation can easily be lost when documents are merged or otherwise manipulated, though, they hardly ever are used.
Furthermore different PDF generating software suites offering a way to add watermarks do so in their respective individual way. Thus, you cannot even recognize watermarks by some special operations done in some specific unique pattern.
Already the iText examples you referred to apply different kinds of watermarks
MovieCountries2 simply draws some gray large Text using an angled base line.
StampStationery copies a complete page from some PDF (which itself may visually have foreground and background material) into a separate object inside the target PDF and adds a reference to this object at the beginning of every page of the target.
InsertPages similarly references a page from some PDF on every newly generated target document page.
Thus, blind watermark extraction is virtually impossible.
Validating watermark content!
You might try some validation, though, if you know what you are searching for. You simply do not merely search some (in PDF not existing) fixed watermark stream but instead the whole page content.
iText offers the classes of the parser package which allow extraction of text and/or bitmap images from content streams. Look at the samples referenced from the keywords PARSING PDF > EXTRACTING IMAGES and PARSING PDF > EXTRACTING TEXT.
You merely have to check whether the image or text which you expect can be found by these classes positioned and styled as you expect.

Updating existing Image and Table fields

I have a pdf built with LiveCycle Designer, I am easily able to update all TextFields using iText 5.4.3. My issue is how do I update the existing ImageField and access a Table object?
I have obtained the position of the image field and am able to add the image onto the form, then remove the image field.
Rectangle rect = acroFields.getFieldPositions("TopmostSubform[0].Page5[0].processFlowImage[0]")
.get(0).position;
String realPath = FacesContext.getCurrentInstance()
.getExternalContext().getRealPath("/");
Image img = Image.getInstance(realPath + wsSelected.getImage());
// use scalePercent as images are process flow diagrams and image
// ratios are not consistent and making them absolute causes distortion
img.scalePercent((float) 47.0);
img.setAbsolutePosition(rect.getLeft(), rect.getBottom());
stamper.getOverContent(5).addImage(img);
While this works, I would think there would, or should, be the ability to get the image field and populate with an InputStream or file.
Another issue is when working with Pre-defined tables on the form. I can get the field names and update the appropriate cells.
However, I have not been able to find any examples of obtaining the table, as a table object, and adding new rows. I can obtain the location, create a new PdfPTable and stamp it onto the form with the data. This will not work. The table will have a dynamic number of rows, based on db data. It is in a flowable layout, between pre-defined text and headers. The form (template) is pre-built and provided as a template. The form is populated with DB values and some user input from a JSF application, and presented back to the user as a finished interface agreement.
My thought is, if I can't access the table object and it's attributes (rows, columns, cells) I would need to read the form, effectively line by line, create and insert the dynamic tables to the output stream when and where they need to be, then continue reading the form and stamping the end result to a new form.

How to insert content in the middle of a page in a PDF using IText

I have a requirement to insert Content into the middle of the page in a PDF.
The Content may be a Dynamic Table or an Image.
My Concept was to first split the PDF into 2 parts, then get the new Content that is to be added and append by replacing a place holder field.
the Splitting is called Tiling as per IText and here is an example for the same.
http://itextpdf.com/examples/iia.php?id=116
The Code above has 2 drawbacks:
1. It splits the page into 16 parts. but that is part of the example. Still i cant figure out a way to split the file into 2 parts only.
2. secondly the split page is converted to a complete page thus disturbing its proportions.
The Rearranging code is the another problem.
The remaining Content should be re-ordered in append mode. but till yet i have only found codes to add complete new pages rather than just the content.
I have found a code that appends the PDF content by replacing a placeholder:
float[] fieldPosition= pdfTemplate.getAcroFields().getFieldPositions("tableField");
PdfPTable table = buildTable();
PdfContentByte cb = stamper.getOverContent(1);
table.writeSelectedRows(0, -1, fieldPosition[1],fieldPosition[4],cb);
Please help me to solve this requirement.
PDF is a presentation format, not an edition format. In other words, it is not designed to allow content insertion, with the original content reflowing gracefully. As a consequence, no tool (at least, none that I know of, and surely not iText) will enable you to achieve what you were given as a requirement.
My advice :
refuse the assignment since it's not feasible, or
get your hands on the original document, insert the desired extra content, and then convert to PDF.

Categories