Incorporating new JRPrinterXXX classes

By: Teodor Danciu - teodord
Incorporating new JRPrinterXXX classes
2002-08-05 07:57


Since there is a growing market for new
JasperReports printer classes that output
to various formats like: HTML, CSV, XLS,
Postscript, ZPL, SATO, etc, I want to ask all of
you interested in this subject to share you opinion
about the best way to incorporate all those in the
main version of the library.

We have to find the best way to host within the
library multiple versions for printers that output in
the same format. For example, we shall end up
having multiple versions for the HTML printer,
since we can produce HTML in very different ways,
with very different results.

I start this thread by making some proposal and I'll
be happy if you could take a moment and give it
a thought:

1. Printer providers should place their printer
classes in their own packages, to avoid name
conflicts (the dori.jasper.engine.print package will
contain only the 3 initial printers: JRPrinterAWT,
JRPrinterPDF, JRPrinterXML);

2. The JasperManager and JasperPrintManager
classes will only access the 3 initial printers (AWT,
PDF, XML) and won't be enhanced to acquire new
printers. In order to print in a special format, the
users will have to work directly with the
JRPrinterXXX class of their choice.
They are advanced users and do not necessary
need a fa ade class to help them with this;

3. Including many printer classes in the main
source tree will make the project larger because
we have to supply all the required libraries for each
of the printer. Creating a different downloadable
package with all the third party printer classes in it
and with the corresponding samples seems to be
a more suitable approach.

Thank you in advance for your replies,

By: Bernd Proissl - berndproissl
RE: Incorporating new JRPrinterXXX classes
2002-08-05 13:52
IMHO end users like an "export" button in the preview windows which then pops up a list of all posible export formats.

Can't this functionality be built by a set of JRPrinterXXX classes which implement a JRPrinter interface?

Parameters could be provided by e.g. a java.util.Map.

In the interface there would be a method like showCustuomDialog() which will pop up a dialog to allow the end user to select specific data (e.g. output file name, XLS format, whether CSV is tab or semikolen delimited...) Defaults of al values could be provided in the parameter map.

Should/must we make a difference between printing an exporting?

Back to your post:
1. An application should be able to add a new implementor of the JRPrinter interface at runtime. My goal is to have an application specific export filter available in the UI without having to change the jasperreports.jar.
2. If there is a good JRPrinter interface the Manager classes could work for all JRPrinters
3. Java as-is is a waste of resources :( So I think we do not have to care about this ;) I'd love to see as much as possible output formats in the core library. :)

These are my thoughts about "We have to find the best way to host within the library multiple versions for printers..."

BTW: What do you think about my JRPrinterAWT for JDK1.4? Are you going to put it in the library or is 1.4 not wide enough distributed? Would this new JRPrinterAWT be part of the core library or should an application provide it by itself?


By: Jason Henriksen - drake42
static laziness.
2002-08-08 16:14
The only advantage is ease. You could totally make a proper singleton such that each client has it's own copy of all the printers, but why? If we register each driver on static init, every map will be the same anyway, so why not reuse the memory?

In other words: I'm lazy. Static is easy, Thus, I like static! : }

By: Jason Henriksen - drake42
RE: Incorporating new JRPrinterXXX classes
2002-08-08 10:53
So based on your proposal, how would this sound:

1) Printers in seperate packages / Add new printers at Runtime:
All printers would need to implement the JRPrint interface. This interface would be extended in two ways. First each printer would have to register itself with a public static HashMap of available printers. The printer class would be required register itself with the constructor in the static initializer. That central repository would become the new preferred way of getting a hold of the list of available printers / printer to use. The Printer would also be required to register as it's full package name. That way "com.managestart.jasper.JRPrinterHTML" can be seperated from "com.funkysoft.jasper.JRPrinterHTML"

2) JRPrintManager will be extended to accept the registration of printers / list printers / hand out a requested printer. There will still be a facade for getting a hold of the object, but once you have the Printer object, you just work with the interface directly.

3) I understand wanting to keep the core library small, but it is also much easier to get all of the available formats at once. What if we copied ant's idea of an optional.jar? We would have a core.jar with the existing three printers, and an optional.jar which contained all of the other known printers. That way the core is still small and easy to try out, but if you're seriously going to use the tool, then you can download all the optional stuff easily. In my schemaMap project I offer the tool with and without common libraries, and almost everyone downloads the whole thing anyway because it is easier. None the less, I think that the choice is very important.

Getting the work done: I am willing to write the central manager if I have CVS access, but it seems to big to do as a patch. Either way, I'm sure any one of use could write it pretty easily. What do you think, Teodor? Also, it seems like many people will want to write printers, and having you commit them to cvs manually is going to be a hassle. Should I start a seperate sourceforge project for the optional.jar? One the other project I would grant cvs access to anyone who wanted to contribue a patch. That way people could directly contribute printers without Teodor having to worry about them in the main code base.

How does all that sound to you guys?

By: Bernd Proissl - berndproissl
RE: Incorporating new JRPrinterXXX classes
2002-08-08 12:41

> 1) ... public static HashMap of available printers.
Why "public static"? What is the advantage for "static"? The disadvantage is that the Map must be shared between clients, but on client may not want to use the others printers. This may not be a problem on the client, but maybe on the server?

>How does all that sound to you guys?
Good :)


By: dorilica - dorilica
RE: Incorporating new JRPrinterXXX classes
2002-08-09 01:25


For the moment, I see only one problem with this:

If you look at those 3 printers already in place:
AWT, PDF and XML, you will find out that they
are very different.

Each one exposes a different interface because
it needs its specific settings and the nature of the
generated output is very different.

This would make very difficult to define a JRPrinter
interface. I tried it once, but achieved nothing due
to those considerations.
So, it's hard for me to imagine how the users will
work with third party printers if there is now such
common interface for them. They have to know
exactly what are the methods they should call on
them and what parameters should they supply.
Also they should know exactly what kind of output
would they receive: single file, multiple files,
in-memory Java objects, etc...

Without a common interface, there is no point on
registering the printers in some Map, because you
cannot work transparently with them. You cannot
say it does not matter with what printer class you
work in your code, from the interface point of view.

I'm puzzled here...

Thank you,

By: Bernd Proissl - berndproissl
RE: Incorporating new JRPrinterXXX classes
2002-08-09 12:09

I must admit I haven't had the time to look very closely at the PDF and HTML printer. So I might be wrong but hopefully my ideas are not depending on any specific printer. :)

Teodor, you say that different printers need different settings. This is true.Where may those settings come from? a) from the report.xml b) from user input c) from the application d) generic use rinput (e.g. print from page 2 to page 5,, 2 copies). Let's build a Map from *all* the data available from the report.xml and pass it to the printer. The prinzter may pick up what it needs. b) user input can be gathered by a showDialog() method. The specific printer will be responsible for handling all the user selections. c) application specific settings can be added to the map from a). d) can be queried from a generic dialog and the results put into the map or this may be queried from the specific printer.

In other words: pass *all* available data to the printer and let it pick up what it needs. Have the printer handle GUI dialogs by itself via a generic method.

Every specific printer must have a workable default setting. This default values can be overwritten by the aplication (via the passed in Map) or by the user (via the mentioned Dialog)

Why should this not work? ;)

Regarding output: Where can the data go: 1) a java supported printer, 2) any nonsupported printer 3) file(s) d) Objects/memory 4) applications (OLE/COM/...)

Every printer should be able to determine the destination from it's input given from a) - d)

About copyright problems: I am not a lawyer but maybe just say "new printers can not be integrated into the main library if they are under a different licensee than the main library"

I can not think about anything against optional.jar (for the moment) :)

I will be mostly offline for 2 weeks, please do not think that I have lost interest... :)


By: Richard S. Hall - rickhall
RE: Incorporating new JRPrinterXXX classes
2002-08-10 08:02
At the very least, you could factor out what is common into the JRPrinter interface and also include a method called something like, getConfigurationObject(). The returned object could follow standard JavaBean techniques to be generically editable by a property sheet dialog box. This may not give a "pretty" dialog box, but it would be usable...

You could also allow JRPrinter implementers to include a custom configuration panel that can edit their corresponding configuration object, thus you can have nice looking dialog boxes too, but in the default case you just use a property sheet if no configuration panel is available.

-> richard

By: Teodor Danciu - teodord
RE: Incorporating new JRPrinterXXX classes
2002-08-09 05:53


There is also the complicate issue of copyright
that we have to consider when incorporating
third party code into the main library.

Thank you,

By: Jason Henriksen - drake42
thoughts on interfaces and copyright
2002-08-09 10:04
I think your common interface point is good to bring up, but over reaching. You stated that with a common interface you cannot work transparently with the printers. However, you cannot work transparently with the printers today, so its no loss. You are completely correct that you will still have to know what class you're going to use, and use it specifically. The only value to the map is that you can do a listing of the available printers. This is nice for letting the user choose what output they want to produce without having to do reflection. You'll still need a case statment so that it can use the chosen printer properly. (If you're program even chooses to support that printer).

On the other hand, most printers will be able to work with a simple interface. All of my printers simply need printReport(JasperPrint jp, Sting destFile) or printReport(JasperPrint jp, OutputStream out). If that was the default, and the printers that were capable of working with that default implemented it, we would be ok 90% of the time. For the 10% where that doesn't work, the method is still there, but it prints an informative error message saying how the printer should be used. That way I could usually work transparently and the weird printers could be ok. We could event go so far as to have to interfaces: JRPrinter which all printers must implement, and JREasyInterfacePrinter which has no methods in the interface, but guarentees that the simple printReport method will work appropriately.

An inteface is also nice so that I know what is a JRPrinter and what isn't in the event that someone names their classes poorly.

As for copyright laws, we really don't have to worry about it. The rule is that you don't put anything in that isn't open source already. If the library you're using is open source, then you doing with it exactly what you are supposed to, so there is no problem. We just provide links to the homepage for each of our libraries in the documentation and we're all done.

BTW, any thoughts on the optional.jar idea?

By: Bernd Proissl - berndproissl
interface proposal
2002-08-29 23:58
I want to distinguish between printing and exporting.
Printing is the resposability for JRPrinterAWT.
Exporting is all the rest.

An exporter might look like:

package dori.jasper.engine.export;

import dori.jasper.engine.JRException;
import dori.jasper.engine.JasperPrint;

public interface JRExporter {
public Object setAttribute(Object name, Object value);
public void export(JasperPrint jasperPrint) throws JRException;
public String getFormatName();

I see two usage scenarios:

a) with user interaction

The exporter's export method will display a dialog (if necessary)
to gather all the information
it needs (filename, fileformat, ...)

JRExporter jrExporter=new AnyJRExporterImplementor(...);
jrExporter.setAttribute("exportWithDialog", new Boolean(true));

The client does not need to know the details of the exporter.

To let the application build a list of all available export formats,
it can query the format from the exporter: getFormatName()

b) no user interaction.
The client of the exporter is aware of the concrete exporter being used,
it may supply all necessary attributes before calling export()

OutputStream os=new SomeOutputStream(...);
JRExporter jrExporter=new OneSpecificJRExporterImplementor(...);
jrExporter.setAttribute("someSpecificAttribute", new Integer(1));
jrExporter.setAttribute("exportOutputStream", os);

The exporter will write all of its output to the output stream.
If necessary it can ignore the output stream and do whatever is necessary
(e.g. OLE Automation).

An exporter should only display a dialog if the attribute exportWithDialog is true
to make sure that it does not block if the thread runs on the server.


By: Teodor Danciu - teodord
RE2: Incorporating new JRPrinterXXX classes
2002-08-30 01:22


OK. Lets say we can agree on these issues:

1. We shall add an new interface called JRPrinter
with the following methods:

public void setParameter(String attributeName, Object value);

public void setParameters(Map values);

public void printReport();

Most of the printer classes will receive a
JasperPrint object and will output in files or
OutputStream objects, but the users would be able
to pass all the printer needs to know using the

This interface will have already defined parameter
names like:

public static final String JASPER_PRINT = "JasperPrint object";
public static final String INPUT_FILE = "Input File";
public static final String OUTPUT_STREAM = "OutputStream object";

This is how such a printer could be used:

MyHtmlPrinter printer = new MyHtmlPrinter();
printer.setParameter(JRPrinter.JASPER_PRINT, myJasperPrintObject);
printer.setParameter(JRPrinter.OUTPUT_FILENAME, "c:\temp\report.html");

2. We can supply also an JRAbstractPrinter to
deal with the parameters manipulation that will
probably be the same for everybody and they will
extend this when creating new printers.

3. I'm reluctant to see any GUI functionality in the
printer classes, especially something that has to
do with entering parameter values.
This is because I'm pretty sure that those who will
want to have dialogs displayed for such purpose
will certainly want to adapt the look and feel of
those windows to their applications.
I would be happy to keep the number of displayable
windows in JasperReports to a minimum.
Let the parent application deal with parameter
gathering as they please.

4. I'm not sure I clearly understand the purpose of
introducing that printer registering mechanism in
the library.
If someone wants to generate XLS output in his
application, besides the PDF and XML defaults,
he has to get the oprtional.jar package and to
decide which of the XLS printer in it is the best.
Then, he makes an "if" in its application to deal
with this particular printer's settings in order to use it.

Why would he want to have the list of the available
printers if he doesn't know how they work and what
are their specific settings? I suppose this is useful
only if each printer has a default behavior that the
guy is willing to accept blindly.

But the user can obtain this list of available printer
just by looking in the API docs. He will have to
write specific code for each of those printers if he
wants to use them properly. So why bother
supplying a list, since each printer will be
somehow hard coded in the parent application

If it is about having an "Export" button in the
JasperViewer, capable of exporting in every
possible format, I think this is also for the users to
enhance the viewer if they want to, either by sub
classing or copying the base code.

Am I getting something wrong here?

5. I the proposed interface is OK with you, I think it
is the moment to create that other project with the
third-party printers.
Jason, you'll be in charge!

This is all for the moment.

Simply put, I want to use the "baby steps"
approach to this:
Lets see the interface in place, lets see the first
third party implementations in the optional package
and then we will think about how to make the use
of them more flexible, if it is not enough.

Thank you,

By: Bernd Proissl - berndproissl
RE_: Incorporating new JRPrinterXXX classes
2002-08-30 02:17

BTW you may have a look at
section "Replace Enums with Classes" which describes
a nice pattern.

You are correct if you want to keep Dialogs poped up out of a Printer to a minimun, but, IMHO generic use is more important than a compatible look-and-feel.

To support applications which need their own LAF
we can choose richard's propsal: add get/setDialogvalues to the interface. The data
herein is maybe different from the data contained in the parameter map. At least not all of the
parameters should be displayed in a dialog (e.g.

I'd love to see the standard viewer having an "export"
button and automatic printer registration, even if it
is only called "viewer" ;)
It allready has a "print" button which also has little to
do view viewing ;)))

Why do you call this *print*, most of it has nothing to do with printing? ;-)


By: Teodor Danciu - teodord
RE: RE_: Incorporating new JRPrinterXXX classes
2002-08-30 04:24


This is the pattern I've been looking for.
You hit the nail on the head. Thank you.

As for the "print" terminology, I guess I was not too
inspired at the beginning and now we're stuck with it.
"Export" would be more appropriate, but I don't
want to confuse people further.
Lets just say now it is more like an euphemism.

Thank you,

By: Bernd Proissl - berndproissl
RE: Incorporating new JRPrinterXXX classes
2002-08-30 05:44
Do not forget to commit to CVS before cutting the release ;)))

Have a nice weekend!


By: Bernd Proissl - berndproissl
RE: Incorporating new JRPrinterXXX classes
2002-08-30 05:03
"now we're stuck with it"
Why?? We are still in beta ;)

>"Export" would be more appropriate, but I don't
> want to confuse people further.
IMHO calling the exporters printers is more confusing.

Why don't we deprecate dori.jasper.engine.JRPrinter[PDF|XML] and the
corresponding manager methods

and parallel we could start a new package under
or dori.jasper.export?

Please let me know if you definitely do not want
to use the term "export" :)

Probably I will have some time next week for this.
I am planning to have JRPrinterAWT and Jason's
JRPrinterCSV and JRPrinterXLS implement the new

Any comments?


By: Teodor Danciu - teodord
RE: Incorporating new JRPrinterXXX classes
2002-08-30 05:25


OK. We shall have a JRExporter interface with the
exportReport() method and stuff.
We shall also have JRExporterParameter class
with defined parameters in it, just like in the pattern
you mentioned.
Maybe also JRAbstractExporter and JasperExportManager.

JRPrinterPDF and JRPrinterXML remain in their
package and become deprecated.
I'll have them implement the new interface and
placed in a new package called
dori.jasper.engine.export, hopefully by Monday,
with the new release.

After that, I expect the promised third-party
exporters to pour in as a new project will be
available for those who want to contribute.

Thank you,

By: Jason Henriksen - drake42
RE: Incorporating new JRPrinterXXX classes
2002-08-30 09:13
Are you moving forward with coding? At this point I've been waiting for somewhere to put stuff. Anyway, if you are moving forward, I'll send you the HTMLPrinter/Exporter as well. (I vote with export as well, btw). Also there is a fix I recently made to the XLS output. (It was possible to have 0 width columns which gives the appearance of missing data)

Let me know if you want me to send you the code, otherwise you can send me the interface and I'll make the changes so we can spread the work out.

Talk to you soon,


By: Teodor Danciu - teodord
RE: Incorporating new JRPrinterXXX classes
2002-09-03 00:30


Yes, I'm moving forward with coding.
I have introduced the JRExporter interface and
I'm currently implementing it for PDF and XML
using the code from the already existing printers.

I only need one or two more days to make some
final tests and update the docs, because this will
be a major release (0.4.0).

I think it would be appropriate for you to see this
JRExporter interface and my implementations
before adding yours.

Thank you,

By: Bernd Proissl - berndproissl
RE: Incorporating new JRPrinterXXX classes_
2002-09-09 02:21

is there any reason why JRExporter does not
have either
public String getFormatName();
public Object getParameter (JRExporterParameter parameter)
public static final JRExporterParameter OUTPUT_FILE_FORMAT = new JRExporterParameter("Output File Format");

Without this a client can not build a list of available export formats (e.g. to present it on the GUI) :(


By: Teodor Danciu - teodord
RE: Incorporating new JRPrinterXXX classes_
2002-09-09 02:43


I'm always open to suggestions.

OK for the getParameter() method.

If you want to directly use the String returned from
the getFormatName() method to display in some
GUI applications, I can tell you that I'm not sure
this is a very good idea.

Such a String (text) would be useless for people
that create applications in Chinese.
It would be more appropriate to have a key for this
format property, and have the application use
a ResourceBundle to translate it in the
corresponding language specific text.
But the name of the exporter class could be that key.

I'm reluctant to see JasperReports becoming
English oriented or harder to internationalize by
introducing hard coded texts with limited usability.

Or maybe I'm getting it wrong here.

Thank you,
2001 JI Open Discussion's picture
Joined: Aug 10 2006 - 3:26am
Last seen: 16 years 10 months ago

1 Answer:

The first post on this thread mention postscript, ZPL and SATO exporter/printers.  Is there any life left in those ideas.  We could benefit greatly from these exporters. 

We would be willing to even engage professional services from Jasper to help move these ideas along.

FYI, we are individual case labels in a Linux environment.  The typical output is to a sheet contains several lables, like avery labels. 

Thank you!


tjahncke's picture
Joined: Jul 30 2006 - 11:02pm
Last seen: 8 years 2 months ago