Table of Contents (Java print, report generate, PDF, Tiff, PNG, BMP, JPG, JPEG, PostScript, and preview/view APIs)
Convert to PDF, TIFF, BMP, PNG, JPG/JPEG, PNG, CSV, PostScript and more
Printing & PDF generation
Programming tips
Which classes to use?
Here is the map of the important classes with name and its functionality.
JavaReportModel - The model class for the JavaReportPrinter holds texts, icons, and 2D graphics before generating report pages. Use its append() method to accumulate the texts, icons, and 2D graphics, table data (TableModel or JTable), Styled/Plain text from a Swing JTextComponent and more. Pass this model to a JavaReportPrinter for printing to a printer.
JTable and TreeTable swing component to a printer.JTree swing component.JList, JComboBox.Yes, you can always preview the output using the SmartJReport preview window. This preview window allow the user to see the pages before they can be printed or PDF generated from the preview window itself. All or selected pages from the preview window can be printed or sent for PDF generation. Look for samples in the downloaded archive.
Back to TopYes, your Java program can automatically print your Java program output to a printer without showing any kind of printer selection, page setup window.
When printing: Use the different print() methods from the appropriate printer class and pass false as the argument for avoid showing printer selection and page setup dialogs. In such case, SmartJReport takes the first one from the discovered printers and sends the output to that printer.
When converting report pages: Use the ConversionFactory class and pass the report
pages as arguments. Look for samples in the downloaded archive.
Yes.
This feature allows you to create Printable pages from various sources and put them together
as a collection of pages (Pageable) that can be PDF generated as a single document,
printed directly to a printer.
For example, if you have a JTextArea, a JTable, and some pages from your Java/J2EE program,
you can generate a PDF document by combining pages from all of these together. You can add
custom pages from virtually any other sources in your Java program to the
ConversionFactory class to generate PDF as a single document.
For all conversion of report pages to other kind of data formats use
ConversionFactory class which has saveAs...() methods.
For example for saving the report pages as PDF document use its saveAsPdf() method.
For report generation use JavaReportPrinter class and its model JavaReportModel class.
For PDF generation on Swing components such as JTable, JTree, JTextArea, JTextPane, JEditorPane, etc. use the
appropriate class mentioned earlier to get a Pageable. Pass the Pageable to the
ConversionFactory.saveAsPdf() methods.
It is very easy to generate Java report output using the SmartJReport classes.
You have to create a JavaReportModel and the add your Java program output into this class.
Finally, pass the JavaReportModel instance to the getPageable() methods
in the JavaReportPrinter class to get a java.awt.print.Pageable. Use
the Pageable as argument to the ConversionFactory.saveAsPdf() methods to generate a PDF
output file.
Here is an example of how you can generate a PDF from a Java JTable or JTree components. Look at the sample source code in the downloadable archive to the complete source files.
JTable table = getJTable();
//Create Pages
PageFormat myPageFormat = new PageFormat(); //create your own page format
JavaTablePrinter tablePrinter = new JavaTablePrinter(); //the printer class for JTable and JTree
tablePrinter.setPageHeaderFooterListener(new DemoHeaderFooterRenderer()); //A Demo Header Footer Renderer
tablePrinter.setFitSmallerTableToPageWidth(true);
tablePrinter.setDrawCellBorder(true);
tablePrinter.setHeaderBold(true);
tablePrinter.setRepeatHeader(true);
tablePrinter.setFitToPageWidth(fitToPaperWidth);
tablePrinter.setPageFormat(myPageFormat);
//Generate PDF from the JTable
Pageable pages = tablePrinter.getPageable(table, PageNoPainter.PAGE_NONE);
OutputStream pdfOutputStream = new PrintStream(new FileOutputStream("./smartjreport.pdf"));
ConversionFactory.saveAsPdf(pdfOutputStream, pageable);
//Print the JTable
pdfPrinter.print(table, pdfOutputStream, PageNoPainter.LOWER_CENTER, false);
Back to Top
When printing or previewing output pages you can let it show a printer setup dialog to choose printer to print, page format, copies, collate, printer job name, fit to page and more options. You may not show the printer dialog but just the page dialog to choose a page format. API provides both option to you.
Showing Print Dialog
Call the print() methods that takes showPrinterDialog as one of the argument. Pass true
if you want to see a printer dialog with other options in it.
Showing Page Dialog
Call the print() methods that takes showPageDialog as one of the argument. Pass true
if you want to see a printer dialog with other options in it. Remember API might have option to pass
both arguments. If you pass both true it will show the printer dialog and will ignore the page dialog
since page dialog is a subset of the printer dialog. On the other hand if you choose to pass
false for showPrinterDialog and true for showPageDialog it will show you a page dialog to choose a page
format for the output pages.
A printer discovery dialog can be shown for the user to select from a list of printers
available where the output might be sent for printing. You can specify a set of printing
attributes as a key/value pait in a HashPrintRequestAttributeSet
object and pass the printer objects print method.
HashPrintRequestAttributeSet pAttrs = new HashPrintRequestAttributeSet();
pAttrs.add(MediaSizeName.ISO_A4); //ISO-A4 page size.
pAttrs.add(Finishings.BIND); //document needs binding.
pAttrs.add(Sides.DUPLEX);
...
docPrinter.print(compToPrint, PageNoPainter.UPPER_RIGHT, false, pAttrs);
The above code segment shows how to specify printing properties to the print method in the JavaDocumentPrinter and AtTablePrinting objects. For example, if none of the printers supports DUPLEX, then there is not going to be any printer selectable for printing the output. It is therefore, suggested to use the print method that takes only first two arguments and discovers all of the printers available.
Back to TopFor printing the pages you must call the any of the print() methods discussed already.
For previewing the output the SmartJ Print API allows you to show a preview frame where al the pages are displayed for you to have a feel of it. In the PREVIEW frame window, you can look at all the pages one at a time. It allows the user to go to a page number. Moreover, the preview frame allows the user to print the pages selectively to a printer.
JTable table;
....
JavaTablePrinter tablePrinter = new JavaTablePrinter();
tablePrinter.preview(table, PageNoPainter.LOWER_CENTER, false);
The above code segment is previewing the content of a JTable using the JavaTablePrinter object.
You can also use the JavaDocumentPrinter object to preview the contenxt of ant
JTextComponent swing components the same way. First argument here is a JTable that needs
to be previewed. The second argument is indicating about where to print the page number on
each page. The third argument cause the API not to show the printer discivery and page
setup dialog to the user.
You might have already noticed that the second argument to the print() and the preview() method is for specifying where to print the page number on the pages to be printed. By default the page number is printed on the lower center of a page using the default location constants PageNoPainter.LOWER_CENTER. If you want to change the page number printing location, might use one of the following constants from the PageNoPainter interface.
PageNoPainter.PAGE_NONE - when you do not want to print a page number on the pages. PageNoPainter.LOWER_CENTER - prints the page number at the lower center on a page. PageNoPainter.LOWER_RIGHT - prints the page number at the lower right hand corner on a page. PageNoPainter.UPPER_CENTER - print the page number at the upper center on a page. PageNoPainter.UPPER_RIGHT - used for printing page number on upper right corner on a page.Back to Top
Add a PageHeaderFooterListener to the printer class to receive a callback on the listener's
setPageHeaderAndFooter(PageHeaderFooterRenderer headerFooterRenderer) method. The
PageHeaderFooterRenderer interface allows you to then use its APIs to get and set
header and footer. It's getPageNumber() will let you know the current page number so
that an appropriate footer and header can be decided.
Following example shows how you can set header and footer to each output pages.
JavaReportPrinter j2eePrinter = new JavaReportPrinter();
JavaReportModel book = new JavaReportModel();
//populate the book with text, icons, 2D graphics.
printerClass.setPageHeaderFooterListener(new PageHeaderFooterListener() {
int pageCount = 0;
public void setPageHeaderAndFooter(PageHeaderFooterRenderer r) {
//System.out.println("setPageHeaderAndFooter()...totalPages=" + r.getTotalPageCount());
AtHeaderFooterElement header
= new AtHeaderFooterElement(null, new Font("Times New Roman", Font.BOLD, 20), Color.decode("#333366"), SystemColor.white, false, AtHeaderFooterElement.LEFT);
AtHeaderFooterElement footer
= new AtHeaderFooterElement("Page " + r.getPageNumber() +"/" + r.getTotalPageCount(), new Font("Arial", Font.PLAIN, 10), Color.decode("#000033"), SystemColor.white, false, AtHeaderFooterElement.CENTER);
if (r.getPageNumber() == 1) {
header.setStr("Employee Information - Manufacturing Division");
}
r.setHeader(header);
r.setFooter(footer);
}
});
When printing header and footer it also prints page number if PageNumberPainter.PAGE_NONE is not passed as the argument. Therefore, depending on what you produce as header and footer enable/disable page number printing.
Back to Top
In the downloaded standalone sample archive you'll find a demo header footer renderer DemoHeaderFooterRenderer.java. You might consider using this demo header footer to customize your header and footer content. Argument bounding box to the APIs are essential input for you to decide the area availbale to you for rendering your content. Argument Graphics object is where you render the content.
One of the important question may be "Do I have control in changing the header and footer bounding box area?". The answer is yes. The bounding box (Rectangle) input to the header footer listener methods are calculated by the API based on the imageableX, imageableY and pageWidth of the PageFormat used while generating the report.
Header Bounding Box - The left out space above the imageableY until about six pixels away from the top edge of the paper area (not imageable area) is considered as the header bounding box. Left hand side (x) of the header bbox starts at six pixels and ends at six pixels away from the extreme right edge of the paper area (not imageable area).
Footer Bounding Box - The left out space below the imageableY + imageableHeight and until about six pixels away from the bottom of the paper area (not imageable area) is considered as the footer bounding box. Left hand side (x) of the footer bbox starts at about six pixels and ends at about six pixels away from the extreme right edge of the paper area (not imageable area).
One - Create and set a PageFormat with appropriate imageableX, imageableY and imageableWidth values. This will give you rest of the areas as mentioned above are the header footer bounds.
Two - You may use only that much space and location of the bounds you need out of the bounds you get from the default PageFormat. In that case use the demo renderer and modify the code to have your own rendering there.
API allows you to zoom the output so that you can reduce or increase number of pages drastically. Zoom on the content can be done programatically as well as from its preview window. Zoom if changes causes the Font of the output text to also change with the same proportion. If the content element is an icon, the zoom is also applied to them for resizing. Usually, prople wants to output the same content using less number of pages. For example, a normal output if takes 10 pages, the zoom out might get the output in just as less as 2 pages or as big as 50 pages or more. The preview window automatically does the compression and expansion automatically for you if the preview window is displayed.
Following code segment shows how you can perform zoom on any kind of content you are printing or
generating PDF document. Each time you apply zoom using the printerClass.setZoom(double percent)
call its getPageable() to test how many pages in the pageable. If further zoom is necessary continue
this process in a look until you got the desired number of pages.
JavaReportPrinter j2eePrinter= new JavaReportPrinter();
JavaReportModel book = new JavaReportModel();
//populate the book instance here.
j2eePrinter.setBook(book);
Pageable pageable = j2eePrinter.getPageable();
if (pageable.getNumberOfPages() >= 5) { //just as an example
j2eePrinter.setZoom(50);
}
j2eePrinter.print(book);
Back to Top
It by default allows you to draw a border around each cell when you print or PDF generate a JTable
swing component using the JavaTablePrinter class. The default cell border is 1
pixel thick and the color of the border is the grid color of the JTable.
In some cases, you might be interested to mark a output JTable cell with a custom cell border. For example, all
cell values that are larger than certain value needs to be marked with a thick border and with
a red color. You can do so, by setting a
AtBorderRenderer to the JavaTablePrinter class using
its setCellBorderRenderer(AtBorderRenderer borderRenderer) method. Each
time a cell border is painted, the drawBorder() interface method is called by
the table output renderer program. Inside the drawBorder method you can paint the border
using the bounding rectangle of the table cell.
JavaTablePrinter tablePrinter = new JavaTablePrinter();
JTable tableToPrint;
//populate the JTable.
tablePrinter.setCellBorderRenderer(new AtBorderRenderer() {
public void drawBorder(JTable table, Object cellValue, int row, int col, boolean isHeaderCell, Graphics g, Rectangle bbox) {
Graphics2D g2d = (Graphics2D)g;
if (!isHeaderCell) {
g2d.setColor(table.getGridColor());
g2d.draw(bbox);
} else {
g2d.setColor(SystemColor.blue.darker().darker());
g2d.drawRect(bbox.x, bbox.y, bbox.width, bbox.height-1);
}
}
});
//preview or print
j2eePrinter.preview(tableToPrint, PageNoPainter.PAGE_NONE, true, frame);
Back to Top
There are two ways you can show the generated PDF from within a browser window.
One: Use PDF Printing and Viewing APIs - Visit our website to find out how.
Two: Using Adobe PDF Viewer - Install Adobe Acrobat PDF viewer if you have not already
installed it. Aceess online demo pages and click on the sample URLs. Alternatively,
you can install our web sample smartjreport_webdemo.war sample and
access the sample URLs.
Download WAR sample ready to deploy under a web container.
How to deploy the EAR file
Unzip it under web server's (e.g. Tomcat) "webapps" directory using Java jar or WinZip utility.
Changes needed after you have unzipped the EAR archive?
Sample already has a default demo license key set. It produce the output pages with a demo string on each page. You
do nothin on the sample other than deploying and accessing the URL from a browser window.
Example of the url is something like: http://host:port//warFileName/
Instead of generating a PDF and showing to browser page, you can print from a server
connected installed printer (print that prints through a printer driver). Call
the print() on an appropriate printer
class or generate a Pageable from the printer class then pass the Pageable to
the PrinterJob.print() method.
(Look for sample in the downloaded archive for the same).
It lets you print or PDF generate output with a number of copies. Each printer class has
the setCopies(int copies) method to let you input the number of copies for
output. When generating PDF document, all of the copies goes to the same document.
When print to a printer, the number of pages printed is (copies x number
of pages in the Pageable).
JavaReportPrinter printerClass = new JavaReportPrinter();
JavaReportModel book = new JavaReportModel();
//populate book.
printerClass.setCopies(2);
printerClass.print(book);
Back to Top
You can show the user a preview window so that the pages can be viewed before sending the
output to a printer or generate a PDF document. The preview window size can be controlled
from your Java program. Use the setPreviewPaneSize(Dimension newSize)
method in the printer class to set the custom preview window size.
JavaDocumentPrinter printerClass = new JavaDocumentPrinter();
JEditorPane editor;
printerClass.setPreviewPaneSize(new Dimension(790, 900));
printerClass.preview(editor);
Back to Top
Adding TAB
It is very simple to use the JavaReportModel class to add lines of text. You can add line break using the \n character as you do for standard output generation from Java System.out.println() methods. You can add a TAB character \t that will put 8 white spaces when rendering the output.
The example next, has a "\t" (TAB) at the beginning to indent the paragraphs. You can insert a tab character at any position in your string.
Adding page break
A page break can be added using the AtPageBreak object or by using the PAGE_BREAK constant defined in the AtElement class.
JavaReportModel book = new JavaReportModel();
book.write(new AtStringElement("How to page break?", titleFont, titleColor));
book.write("\n\n\tBefore this paragraph, there is a page break added. So don't get surprized if " +
"this heading is always shown at the beginning of a new page leaving empty " +
"spaces in the previous page. Typically in a J2EE program, you can add lines " +
"of text and put a page break at any position.");
//Try page break
book.write(AtElement.PAGE_BREAK);
book.write("\n\n\tA page break can be added using the AtPageBreak object or by " +
"using the PAGE_BREAK constant defined in the AtElement class.");
book.write("\n\nAs an example, both of the above two paragraphs has a \"\\t\" (TAB) at the beginning " +
"to indent the paragraphs. You can insert a tab character at any position " +
"in your string.");
Back to Top
In order to change the preview window button properties such as its icon, tooltip, making them visible/invisible,
enable/disable, get the AtPreviewFrame reference from the printer class you have created.
Get the refernece to one or more of the buttons from the preview window and appropriate mehtods to chage them.
JavaDocumentPrinter docPrinter = new JavaDocumentPrinter();
Component currWindow;
JTextArea textDocumentEditor;
//populate the JTextArea.
docPrinter.preview(textDocumentEditor, PageNoPainter.LOWER_CENTER, false, currWindow);
//
AtPreviewFrame previewWindow = docPrinter.getPreviewWindow();
previewWindow.setViewerControlVisible(AtPreviewFrame.PDF_BUTTON, false);
previewWindow.setViewerControlTooltipText(AtPreviewFrame.PRINT_BUTTON, "Print selected pages");
previewWindow.setPreviewButtonImage(AtPreviewFrame.PRINT_BUTTON, myIconImage);
previewWindow.setViewerControlEnabled(AtPreviewFrame.GO_BUTTON, false);
.... ....
Back to Top
JavaTablePrinter
class
It is only couple of lines of code to use the JavaTablePrinter
class for printing a JTable content. It breaks the rows and columns into multiple pages.
If there are large number of columns in the table, page break happens column wise
(vertically) as well. How many rows can be printed on a page is decided by the font of the
rows and columns in the JTable. Similarly, how many columns can be accomodated in a page
is decided by the maximum width of the data elements of the columns and the available
width of the print media.
JavaTablePrinter
object
In your class use the next code segment for having handle to the table printer object.
private JavaTablePrinter printer = new
JavaTablePrinter();
The constructor do not take any arguments. Once an object is created it can be reused
for printing multiple JTable by calling its overloaded print() methods.
The default setup in the JavaTablePrinter object prints the table cells
However, if you can always change these printing properties by calling the following methods.
Printing border around the cellssetDrawCellBorder(boolean cellBorder)
- Draws a cell border around each cell value.
setRepeatHeader(boolean repeatHeader) -
Flag indicates that the header information (column names) must be repeated on each page
when broken into number of pages.
setHeaderBold(boolean headerBold) -
Indicates, if the argument is true then the header information is printed with bold face
font. The false argument indicates the header will be printed with a normal font.
The following code segment prints the JTable content where there is no cell border is drawn around each cell value, header information (column names) are not repeated on each page other than the very first set of pages (more than one page if splitted vertically). The header information is printed with bold face font.
private JavaTablePrinter printer = new JavaTablePrinter();
printer.setDrawCellBorder(false);
printer.setRepeatHeader(false);
printer.setHeaderBold(true);
Simply call one of the many print methods in the JavaTablePrinter class. Following is the simplest print() method prints the content to a printer.
JTable table;
....
printer.print(table, PageNoPainter.LOWER_CENTER);
The second argument is the location where the page bumber to be printed.
Back to Top
If you your JTable to be printed the way it is displayed you have to set
setUseCellRenderer(boolean) to true. Otherwise API will automatically
try to expand the content of the cell
and create multiple pages breaking the rows and columns so that no part of the cell content is lost.
Just after the call to the preview() method of the printing classes, change the button icons, hide,
chage tooltip etc. using the methods defined in the AtPreviewFrame class shown next:
printer.preview(thingToPrint, PageNoPainter.LOWER_CENTER, true);
AtPreviewFrame previewFrame = printer.getPreviewWindow();
previewFrame.setViewerControlVisible(AtPreviewFrame.PDF_BUTTON, false);
previewFrame.setViewerControlTooltipText(AtPreviewFrame.PRINT_BUTTON, "Print the pages");
previewFrame.setPreviewButtonImage(AtPreviewFrame.PRINT_BUTTON, [your own ImageIcon]);
previewFrame.setViewerControlEnabled(AtPreviewFrame.GO_BUTTON, false);
The above code segment does the following after getting the preview frame reference.
Use JavaTreePrinter class and call print() method to print a JTree. Call
preview() to preview it and getPageable() to get a Pageable consists
of AbstractPage pages. For convert to documents such as PDF, TIFF and PostScript or images such
as PNG, BMP, GIF, JPEG/JPG use the conversion APIs in ConversionFactory.saveAsXXX() methods.
For code sample look for JTreePrintDemo.java in the downloaded archive and
run JTreePrintDemo.bar or .sh script file from a command window.
When printing any of the JTextField, JTextArea, JTextPane, and JEditorPane components, you can pass the component directly to the print() or the preview() methods in the JavaDocumentPrinter object.
Create an JavaDocumentPrinter objectJavaDocumentPrinter docPrinter = new JavaDocumentPrinter();
The constructor has no arguments to pass. The print method takes the JTextComponent (any of its derived class such as JTextField, JTextArea, JTextPane, JEditorPane etc.) as the first argument, and the page number location as the second argument.
Printing
JTextComponent textComponent = new JTextPane();
....
docPrinter.print(textComponent, PageNoPainter.LOWER_RIGHT);
Pass the JTextComponent reference to the print method for printing. It uses the JTextComponent Document model for getting the data elements, its fonts, styles and more before rendering to the printer.
PreviewingPreview is similar to the print method call. All you do is to call the JavaDocumentPrinter's preview method and pass the same arguments. In addition, it takes a third argument boolean true or false indicating whether you want to show the setup dialog for the user to specify the page margins, and page orientation etc.
docPrinter.preview(textComponent, PageNoPainter.LOWER_RIGHT, true);
If the third argument is "true" then a page setup dialog is displayed for the user to setup the page margins and decide the media orientation. The "false" argument will cause no page setup dialog to show up.
Back to Top