Home
Analytics
Auto Text - Page n of m (spacing)
bmuskie
Hi,
I have put "Page n of m" under the master page. And, I can't figure out how to make it display nicely.
For instance, I want the Column A with the title as "Page:" and Column B with "Page n of m" and display as:
Page: 12/13
But the report will shown as:
Page: 12___/___13
Of course, I could adjust the individual column width to the "Page n of m" grid. Then make the grid column A (right align), B (centre) and C (left align).
But I just can't manage to make it perfect if the column width is fixed.
i.e.
Page: __1/200
Page: __2/200
...
Page: _18/200"
..
Page: 104/200
Is there any easy way to achieve this?
Note: I put the "___" for easy reading under the html
Find more posts tagged with
Comments
mwilliams
Hi bmuskie,
What version of BIRT are you using?
So, you're wanting to not have the spaces between "Page:" and the actual page number? Is this correct?
bmuskie
Hi Michael,
Yes, I don't want to have the extra spaces between the "Page:" and page number. And, I'm currently using 2.5.0.
Thanks!
bmuskie
Hi mwilliams,
Correct. And, I'm using 2.5.0.
Thanks!
mwilliams
bmuskie,
By using a page variable and a custom page counter, I was able to get rid of the Page: __1 spaces and make it Page: 1, but right justify didn't seem to work in the page variable auto text element, so there was a large space between 1 and '/'. The look you currently have is probably the better of the two. I'll let you know if I think of anything else that could help.
Migrateduser
I was able to adopt an example given by Bruno Lowagie (<a class='bbc_url' href='
http://1t3xt.info/examples/browse/?page=example&id=223'>1T3XT
: Examples</a>) such that the text "Page n of M" will be rendered correctly in the case of M>9 as well.<br />
<br />
The idea is to create one PdfTemplate (=PDF XObject in iText-speak) per page. For the full source code (including a lot of comments) see below.<br />
<br />
It should be possible to adopt this technique into BIRT, but right now I don't have the time and expertise to do so.<br />
<br />
However, probably only the package org.eclipse.birt.report.engine.emitter.pdf would have to be changed, namely the PDFPage.java, PDFPageDevice.java and PDFRender.java.<br />
<br />
I am thinking of a solution that uses a special style name "PageNofM" to detect that the given text should be completely rendered using a PdfTemplate.<br />
This could replace the existing half-way solution using Autotext and setPDFTemplate.<br />
<br />
Well, here's the iText example:<br />
<br />
/* in_action/chapter14/PageXofY.java */<br />
<br />
import java.io.FileOutputStream;<br />
import java.io.IOException;<br />
import java.util.ArrayList;<br />
import java.util.List;<br />
<br />
import com.lowagie.text.Document;<br />
import com.lowagie.text.DocumentException;<br />
import com.lowagie.text.Element;<br />
import com.lowagie.text.ExceptionConverter;<br />
import com.lowagie.text.Paragraph;<br />
import com.lowagie.text.Phrase;<br />
import com.lowagie.text.Rectangle;<br />
import com.lowagie.text.pdf.BaseFont;<br />
import com.lowagie.text.pdf.PdfContentByte;<br />
import com.lowagie.text.pdf.PdfPageEventHelper;<br />
import com.lowagie.text.pdf.PdfTemplate;<br />
import com.lowagie.text.pdf.PdfWriter;<br />
<br />
/**<br />
* This example was written by Bruno Lowagie. It is part of the book 'iText in<br />
* Action' by Manning Publications. <br />
* ISBN: 1932394796<br />
* <a class='bbc_url' href='
http://www.1t3xt.com/docs/book.php'>http://www.1t3xt.com/docs/book.php</a>
; <br />
* <a class='bbc_url' href='
http://www.manning.com/lowagie/'>Manning
: iText in Action</a><br />
* <br />
* Adopted by Henning von Bargen, Triestram und Partner GmbH, 2010-05-27,<br />
* to support the case of more than 9 pages (up to 9999 pages).<br />
*/<br />
<br />
public class Test2 extends PdfPageEventHelper {<br />
<br />
/** The PdfTemplates that contain the pageNofM text (one for each page). */<br />
protected List<PdfTemplate> pageNofM;<br />
<br />
/** The font that will be used. */<br />
protected BaseFont helv;<br />
<br />
/** The font size */<br />
private int fontSize = 12;<br />
<br />
/** The maximum width for the pageNofM text */<br />
float maxWidth;<br />
<br />
/**<br />
*
@see
com.lowagie.text.pdf.PdfPageEvent#onOpenDocument(com.lowagie.text.pdf.PdfWriter,<br />
* com.lowagie.text.Document)<br />
*/<br />
public void onOpenDocument(PdfWriter writer, Document document) {<br />
pageNofM = new ArrayList<PdfTemplate>();<br />
try {<br />
// Create the font for rendering the pageNofM text.<br />
helv = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI,<br />
BaseFont.NOT_EMBEDDED);<br />
// Compute the maximum size of the pageNofM text.<br />
// We need this because we are using a PdfTemplate (aka XObject).<br />
// This is basically a rectangle with a predefined size<br />
// whose context you define elsewhere (read: later).<br />
maxWidth = helv.getWidthPoint("Seite 0001 von 9999", fontSize);<br />
} catch (Exception e) {<br />
throw new ExceptionConverter(e);<br />
}<br />
}<br />
<br />
/**<br />
*
@see
com.lowagie.text.pdf.PdfPageEvent#onEndPage(com.lowagie.text.pdf.PdfWriter,<br />
* com.lowagie.text.Document)<br />
*/<br />
public void onEndPage(PdfWriter writer, Document document) {<br />
<br />
PdfContentByte cb = writer.getDirectContent();<br />
<br />
// We don't want the pageNofM to change the state for the rest of the page<br />
cb.saveState(); <br />
<br />
// The base line should be 20 points below the bottom margin.<br />
float textBase = document.bottom() - 20; <br />
<br />
// create a PdfTemplate for pageNofM of size (maxWidth, 100)<br />
PdfTemplate total;<br />
total = writer.getDirectContent().createTemplate(maxWidth, 100);<br />
// and a slightly bigger bounding box to prevent clipping the<br />
// rightmost characters caused by possible rounding errors.<br />
total.setBoundingBox(new Rectangle(-20, -20, maxWidth + 20, 100));<br />
<br />
// add the PdfTemplate to the list. Its content will be defined<br />
// later in onCloseDocument.<br />
pageNofM.add(total);<br />
<br />
// Position the PdfTemplate on the page on the outer side.<br />
// That at the left for odd page numbers ...<br />
if ((writer.getPageNumber() % 2) == 1) {<br />
cb.addTemplate(total, document.left(), textBase);<br />
}<br />
// and at the right for even page numbers.<br />
else {<br />
cb.addTemplate(total, document.right() - maxWidth, textBase);<br />
}<br />
cb.restoreState(); // restore the original page state <br />
}<br />
<br />
/**<br />
*
@see
com.lowagie.text.pdf.PdfPageEvent#onCloseDocument(com.lowagie.text.pdf.PdfWriter,<br />
* com.lowagie.text.Document)<br />
*/<br />
public void onCloseDocument(PdfWriter writer, Document document) {<br />
// Total number of pages<br />
int numPages = writer.getPageNumber() - 1;<br />
for (int page=1; page<=numPages; page++) {<br />
// For each page, we have one PdfTemplate<br />
PdfTemplate total = pageNofM.get(page-1);<br />
// Determine the text to be rendered...<br />
String text = "Seite " + page + " von " + numPages;<br />
// and calculate its width.<br />
float textSize = helv.getWidthPoint(text, fontSize);<br />
total.beginText();<br />
total.setFontAndSize(helv, fontSize);<br />
// Position the text (relative to the PdfTemplate's origin).<br />
if (page % 2 == 1) {<br />
// For odd page numbers, no offset is needed. <br />
total.setTextMatrix(0, 0);<br />
} else {<br />
// For even page numbers, take into account that<br />
// the actual text width is less than the maxWidth,<br />
// so move it to the right accordingly.<br />
total.setTextMatrix(maxWidth - textSize, 0);<br />
}<br />
total.showText(text);<br />
total.endText();<br />
}<br />
}<br />
<br />
/**<br />
* Generates a file with a header and a footer.<br />
* <br />
*
@param
args<br />
* no arguments needed here<br />
*/<br />
public static void main(String[] args) {<br />
System.out.println("Chapter 14: Page X of Y Example");<br />
System.out.println("-> Creates a PDF file with page numbers.");<br />
System.out.println("-> jars needed: iText.jar");<br />
System.out.println("-> files generated:");<br />
System.out.println(" test2.pdf");<br />
// step 1: creation of a document-object<br />
Document document = new Document();<br />
try {<br />
// step 2:<br />
PdfWriter writer = PdfWriter.getInstance(document,<br />
new FileOutputStream("test2.pdf"));<br />
writer.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft);<br />
writer.setPageEvent(new Test2());<br />
document.setMargins(36, 36, 36, 54);<br />
// step 3:<br />
document.open();<br />
Paragraph p = new Paragraph();<br />
// step 4: we grab the ContentByte and do some stuff with it<br />
for (int k = 1; k <= 140; ++k) {<br />
p.add(new Phrase("The Quick brown fox jumps over the lazy dog. "));<br />
}<br />
p.setAlignment(Element.ALIGN_JUSTIFIED);<br />
for (int k = 1; k <= 12; ++k) {<br />
document.add(p);<br />
}<br />
} catch (DocumentException de) {<br />
System.err.println(de.getMessage());<br />
} catch (IOException ioe) {<br />
System.err.println(ioe.getMessage());<br />
}<br />
document.close();<br />
}<br />
}
kosta
Hello BIRT Community,
I have the same problem like the one described here.
I am trying to make paging like "Page 3 of 111" but for that I must reserve place for the whole number length (Page __3 of 111).
Is there any solution for this one?
Has someone tried to implement the code shown in this post?
Is there any variable like pageNumber for totalPage. In my examples they have the same value.
If those two parameters could be used on every page maybe then some scripting could help to solve this problem.
Thanks in advance.
mwilliams
Hi Kosta,
You could use page and report variables to store the total page and current page values and recall them using the auto text variable display element. You'd make a report variable that is set to totalPage and a page variable that is set to something like "Page: " + vars["varName"] + " / "; Then, in your master page footer, you could use the variable auto text elements set to display "in-line" and your space issue should be taken care of.
Let me know if you need an example.
kosta
Thanks for the reply Michael Williams.
One example would be very useful and helpful.
Thank you in advance.
kosta
Hi mwilliams,
can you post the example that you mentioned before please.
Thank you.
mwilliams
Kosta,
Sorry, I was off for Thanksgiving holiday. What is your BIRT version?
kosta
Hello Michael,
I am using BIRT 2.6.1
Thank you in advance.
mwilliams
Kosta,
I made a quick example. It works in the Web Viewer and if you export to PDF from the Web Viewer. It does not work if you try to go to PDF directly from the designer. Let me know if you have questions.
kosta
Thank you Michael,
after adding new variable for the "from"-term and edit its margin in the properties window I have the demanded solution.
Is there any way to do that directly from the Report Designer?
The problem there is that the total page number variable is equal to the page number and the first page is not count. The same problem when I am using the BIRT API.
Thanks.
mwilliams
Kosta,
I'm not sure I'm quite understanding. Can you explain a little more?
Does the report that I posted in here show the same number for page and total page when you view in the BIRT viewer from the designer?
kosta
Michael <br />
<br />
as you mention<br />
<br />
<blockquote class='ipsBlockquote' data-author="'mwilliams'" data-cid="70849" data-time="1291130205" data-date="30 November 2010 - 08:16 AM"><p>
Kosta,<br />
<br />
I made a quick example. It works in the Web Viewer and if you export to PDF from the Web Viewer. It does not work if you try to go to PDF directly from the designer. Let me know if you have questions.<br /></p></blockquote>
<br />
It works in the Web Viewer and if you export to PDF from the Web Viewer.
And it really works that way.<br />
It does not work if you try to go to PDF directly from the designer.
But I need the second one. Here I have the problems described in my previous post.<br />
<br />
Any workaround for that one would help me a lot. Thank you.
mwilliams
So, you will just be directly running this from your designer? Not deploying it?
I'm guessing the issue here is that the web viewer does the run then render tasks and the rest do the run and render task. Don't know that you'll find a way around this for the PDF from the designer.
07ersh
<blockquote class="ipsBlockquote" data-author="mwilliams" data-cid="70952" data-time="1291300860">
<div>
<p>So, you will just be directly running this from your designer? Not deploying it? I'm guessing the issue here is that the web viewer does the run then render tasks and the rest do the run and render task. Don't know that you'll find a way around this for the PDF from the designer.</p>
</div>
</blockquote>
<p>Hello, <span style="color:rgb(40,40,40);font-family:'Source Sans Pro', sans-serif;">Michael. I have the same situation: when I generate report as In Web Viewer, I have current result (1/9, 2/9,..). But when I direst generate report as PDF I have wrong result (00, 1/1, 2/2). In PPRT I have always paginate result as 1/1 for all pages.</span><br>
Could you suggest a solution if there is one?<br><span style="color:rgb(40,40,40);font-family:'Source Sans Pro', sans-serif;">Thank you in advance<br><br>
</span></p>