Its been a while, but after some family commitments, I am finally back at it with BIRT. In April of 2006, I created a post discussing how Styles could be used within BIRT. With the release of 2.2, it is time to revisit CSS Styles in BIRT. The biggest change is that you can now link to a CSS style sheet, the styles do not need to be imported into the report. This is a HUGE improvement.
To take advantage of this feature you go to the outline view, right click on styles and get the following dialog.
The new option allows you to "Use CSS File". When you select this file a dialog that enables you to select a file.
Once you have attached the CSS file, you will then have access to any of the classes in the CSS file to use as styles within your report. But this is just the beginning. All of the major objects and positions within a BIRT report have a default style associated with them. By modifying the default style settings you can change the look of your report without having to set any styles manually.
The best place to start with the pre-defined styles is to start with the visual objects that make up the report the controls. Each control type has a default style associated with it.
- text
- label
- text
- data
- image
- text-data
So adding the following entry in your style sheet will change the default behavior of all text controls to be orange.
color: orange;
}
In reality, one should be very careful with how many changes are made to the lowest level styles. Changing a property for a basic control style, will change the style for all instance of that control, unless the control specifically over-rides the property. So if you want all of your text to be orange, by all means modify the base control classes. If on the other hand, you want to modify report style by position within the report, then read on. In other words, if you want the header for all of your tables to look one way and the detail to look another, BIRT provides default classes that control that behavior.
Before moving into the full array of BIRT default classes, I want to expose the CSS properties that BIRT supports. The following table documents the properties and the default property values that BIRT uses.
CSS Property | Values | Default | Inherit |
---|---|
background-attachment | scroll | fixed | inherit |
| <color>| transparent | inherit |
background-image | <uri> | none | inherit |
background-position | [ [ <percentage> | <length> | left | center | right ] [ <percentage> | <length> | top | center | bottom ]? ] | [ [ left | center | right ] || [ top | center | bottom ] ] | inherit |
background-repeat | repeat | repeat-x | repeat-y | no-repeat | inherit |
border-top-color , border-right-color , border-bottom-color , border-left-color | <color> | transparent | inherit |
border-top-style , border-right-style , border-bottom-style , border-left-style | <border-style> | inherit |
border-top-width , border-right-width , border-bottom-width , border-left-width | <border-width> | inherit |
color | <color> | inherit |
display | inline | block | list-item | run-in | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit |
font-family | [[ <family-name> | <generic-family> ] [, <family-name> | <generic-family>]* ] | inherit |
font-size | <absolute-size> | <relative-size> |<length> | <percentage>| inherit |
font-style | normal | italic | oblique | inherit |
font-variant | normal | small-caps |inherit |
font-weight | normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit |
letter-spacing | normal | <length> | inherit |
line-height | normal |<number> | <length> | <percentage> | inherit |
margin-right , margin-left | <margin-width> | inherit |
margin-top , margin-bottom | <margin-width> | inherit |
orphans | <integer> | inherit |
padding-top , padding-right , padding-bottom , padding-left | <padding-width> | inherit |
page-break-after | auto | always | avoid | left | right | inherit |
page-break-before | auto | always | avoid | left | right | inherit |
page-break-inside | avoid | auto | inherit |
text-indent | <length> | <percentage> | inherit |
text-align | left | right | center | justify | inherit |
text-decoration | none | [ underline || overline || line-through || blink ] | inherit |
text-transform | capitalize | uppercase | lowercase | none | inherit |
white-space | normal | pre | nowrap | pre-wrap | pre-line | inherit |
widows | <integer> | inherit |
word-spacing | normal | <length>|inherit |
vertical-align | baseline | sub | super | top | text-top | middle | bottom | text-bottom | <percentage> | <length> | inherit |
Most of you are probably familiar with the standard HTML cascade:
Table
tr
td
A td element will inherit from either the table or the row if it has not defined its own value. If you do specify a property value for the td selector, than it will over-ride the values set at both the row and table levels.
BIRT uses its own cascade precedence. Since each of the major objects and functional positions is assigned a default style. The next table shows the precedence used for the BIRT default styles.
Controls | |||||||||
| data | ||||||||
| image | ||||||||
| label | ||||||||
| text | ||||||||
| text-data | ||||||||
report | |||||||||
| page | ||||||||
| grid | ||||||||
| list | ||||||||
| list-header | ||||||||
| list-detail | ||||||||
| list-footer | ||||||||
| list-group-footer-1 | ||||||||
| . . . | ||||||||
| list-group-footer-9 | ||||||||
| list-group-header-1 | ||||||||
| . . . | ||||||||
| list-group-header-9 | ||||||||
| table | ||||||||
| table-header | ||||||||
| table-header-cell | ||||||||
| table-detail | ||||||||
| table-detail-cell | ||||||||
| table-footer | ||||||||
| table-footer-cell | ||||||||
| table-group-header-1 | ||||||||
| table-group-header-cell | ||||||||
| . . . | ||||||||
| table-group-header-9 | ||||||||
| table-group-footer-1 | ||||||||
| table-group-footer-cell | | |||||||
| . . . | ||||||||
| table-group-footer-9 | ||||||||
TOC-level-0 | |||||||||
. . . | |||||||||
TOC-level-9 |
So if you want to change the font-family for all of the controls within your report, then you can use the following within your CSS document.
font-family: sans-serif;
}
If you want the tables in the report to use italics and a serif font, then you would add:
font-family: sans-serif;
font-style: italics;
font-family: serif;
}
As you can see, you can control the behavior for headers, detail sections, and footers for list and tables. In addition, each of the group headings can use its own style up to 9 levels deep. In the previous article, I provided a CSS document that was setup to take advantage of this feature. Unfortunately, the Default Style Names have changed between 2.1 and 2.2. I have revised the style-sheet to work with the new default style names.
font-size : medium;
font-weight : bold;
color : #FFFFE0;
.table-group-header-1 {
border-bottom : double;
border-top : solid;
border-top-width : thin;
border-color : #FFF8DC;
.table-group-header-2 {
border-bottom : double;
border-top : solid;
border-top-width : thin;
border-color : #FFF8DC;
font-size : small;
.table-header {
border-bottom : double;
border-top : solid;
border-top-width : thin;
border-color : #483D8B;
.table-detail {
font-size : small;
font-weight : bold;
color : #4682B4;
.table-footer {
border-top : double;
border-bottom : solid;
border-bottom-width : thin;
border-color : #483D8B;
font-size : x-small;
I am hopeful that in the next edition, I can take a look at adding a bit of code to the report that will do more to automatically assign styles to reports, even if you are using custom styles. I will let you know when I get it done.
45 comments:
Hi,
i use tomcat 5.5.23 with birt 2.2 to generate report.
one thing i found strenge is although i set the OutputStream using RenderOption.setOutputStream to a File in another location, the generated report will be always in tomcat_home/bin order and an another report with the same name but with size 0KB in defined location.
is it a bug or have i forget something?
thanks in advance
have found the problem, it's my mistake, also use setOutputFileName at the same time
Hi
I'm using the CSS feature as well in our projects.
What about including other CSS files into the CSS file used within BIRT? Is this supported?
BIRT can use CSS style sheets that are imported into the report or if you are using the 2.2 branch you can use style sheets that are located in the resource folder by using the "use sytle sheet" option within the report. This is located in the same place as the import.
Jason
CSS supports the "import" of other CSS files.
If I try to use such a CSS file, BIRT recognise only the styles defined in the first CSS file.
Example: a.css defines some style and "import" the b.css.
In b.css there are different styles defined. If I do "use style sheet" with the a.css, I do not see the styles defiened in b.css within my report! Is this not supported in BIRT or is this a bug?
This sounds like a bug. Can you please log a bugzilla entry?
some onmouse event will be good.
Hi,
We are using Tomcat 5.5.23 and BIRT2.2.0 version.
I have linked style sheet which is places under resource folder. When we execute the report it is taking the style sheet and displaying the report properly but, when I open parameter page and click on ok, it is not taking the styles linked.
This is working fine when we completely reload the report and not just changing the parameters in opened report.
Can any one help me to resolve this issue?
Thanks in advance.
Is it possible, to use a css or a style for a chart or do I have to do this with "setCustomXML" functionality?
Thx in forward
Ben
Is it possible to have a separate style used for different media types (i.e. screen v. print)?
I am able to make my reports look nice on screen, very readable, with colors and nice fonts, but when printing my reports, the fonts are too large to nicely fit each row of data into one line without making all reports print landscaped.
Any insight would be appreciated.
Thanks,
Keith
Keith,
This is possible. Create two styles in the report. One for pdf and one for everything else and then use a script like the following in the beforeFactory:
(Notice you will need to name your elements)
tableHandle = reportContext.getDesignHandle().findElement("mytable");
rowHandle = tableHandle.getDetail().get(0);
reportContext.getOutputFormat();
if( reportContext.getOutputFormat() == "pdf" ){
rowHandle.setStyleName("style2");
}else{
rowHandle.setStyleName("style1");
}
Jason,
Your example works in that case, but I was unclear in my previous question. I am using the "WebViewerExample" to quickly integrate the reports for my end users. They will be viewing the reports via a web browser, but will likely want to print some of the reports locally for later use. The reports look nice on screen, but when they print from the web viewer, the report becomes very hard to read.
Is there a way to specify a style just for printing when a report is in HTML format?
Thanks,
Keith
Keith,
Are they printing with browser print button or the print icon in the viewer toolbar. If they are using the icon it creates a pdf, so you should be able to change the style in the onRender event instead of the onCreate event.
Jason
Jason,
They are using the print icon in the viewer.
Whenever I move that code snippet to set the style out of the "beforeFactory" event, it no longer sets the style of my data table. What am I missing?
Thanks,
Keith
Keith,
Try removing the code from the beforeFactory, select the table row and edit its onRender event with something like this:
if( reportContext.getOutputFormat() == "pdf" )
{
this.getStyle().backgroundColor = "red";
}
Jason
Jason,
Thanks for the tip, that works. However, from my tests so far, it does mean hard coding the style values into the "onRender" event of each element.
To avoid hard coding my style values, I've tried creating a simple java class to set style values for a passed element. The Java class is very simple and has a method "format" that looks like:
public void format(IReportElementInstance element, String elementType) {
element.getStyle().setFontFamily("Monospace");
element.getStyle().setFontSize("6.7pt");
}
I have called this method from the "onRender" event, but with no success (or error messages).
I've tried writing a simple JavaScript that did something similar, but I could not get the report viewer to recognize my JavaScript file (I put it into the "scriptlib" directory).
Are there any other available methods for setting style values in the event handers?
Thanks,
Keith
Keith,
If you implemented something in a js file you should be able to include this js file by selecting the report->properties->resources and click the add button under javascript files. This js file needs to be in your resource folder.
If you stick with the java approach, jar your class and put it in the web-inf/lib directory. How did you call the class?
Jason,
In the initialize event of the report:
printformatter = Packages.com.familyvideo.reportutils.VMCRPrintFormat();
My thought was this should create a global variable that I can use throughout the other events (similar to a scripted data source that I've used in another report).
Then in the onRender event of the table row I have this code:
if(reportContext.getOutputFormat() == "pdf") {
printformatter.format(this, "datarow");
}
This seemed like a logical solution to me, but I have not been able to get it to work. I would like to stay with Java as I can package it with other Java utility classes I have used for other reports.
Thanks,
Keith
Keith,
I am not certain how you are running the report (2 task or 1 task) but using the global variable approach is ok if you set it like:
printformatter = Packages.com.familyvideo.reportutils.VMCRPrintFormat();
reportContext.setPersistentGlobalVariable( "myfunction", printformatter);
Then when you want to use it:
reportContext.getPersistentGlobablVariable( "myfunction").format();
Jason,
When trying to use the setPersistentGlobalVariable method, I get the error:
There are errors evaluating script "printformatter = Packages.com.familyvideo.reportutils.VMCRPrintFormat(reportContext.getHttpServletRequest()); reportContext.setPersistentGlobalVariable("PrintFormatter", printformatter);": Can't find method org.eclipse.birt.report.engine.script.internal.ReportContextImpl.setPersistentGlobalVariable(string,com.familyvideo.reportutils.VMCRPrintFormat).
So, my class is not recognized by this method.
I tried to use the method you described to attach the JavaScript file to the report, but I still go an error:
org.eclipse.birt.report.engine.api.EngineException: Unable to load Script file print_format.js.
BTW, I'm using the frameset pattern to run the report (which is the 2 task method if I understand correctly).
Thanks,
Keith
Keith
1 - In the java scenario where are you getting the error. In what script. BTW move the code to the beforeFactory. It only gets called once. initialize gets called twice with /frameset.
2 - In js scenario where did you put the js file?
Jason,
1 - The error comes from whichever event the printformatter = Packages.com.familyvideo.reportutils.VMCRPrintFormat("report_missing.rptdesign"); reportContext.setPersistentGlobalVariable( "PrintFormatter", printformatter);" lines are in. The error is persistent across all methods of running the report (preview, web viewer from the designer, and deployed web viewer).
2 - I was able to get the js file put in the right place to get it to work, but using javascript for this solution makes this less robust and more difficult for the other developers in my group to support in the future.
If you call
printformatter = Packages.com.familyvideo.reportutils.VMCRPrintFormat("report_missing.rptdesign");
only when you need it does it work? I am wondering if it ever finds your class?
Jason,
I tried moving the initialization of my class as you suggested an started watching the log files for issues and found why it is failing (and found a possible solution).
Here is the error from the log:
Cannot convert [object Object] to org.eclipse.birt.report.engine.api.script.instance.IReportElementInstance (/report/body/table[@id="31"]/method[@name="onRender"]#3).
As it turns out, the object passed as this from the onRender event is a org.mozilla.javascript.NativeObject . So, I can pass the StyleInstance object instead. That works...
Also, I've moved the initialization of the class into the beforeRender event for the report (without using the reportContext.setPersistentGlobalVariable method) and it is working like I had hoped.
As always, you have been very helpful in figuring out how to solve the problem!
Thanks,
Keith
Keith,
Glad to hear. I forgot that setPersistentGlobalVariable requires that the object be serializable.
Jason
I was able to get the above to work in the designer, but when I deploy it to a tomcat instance (apache version 5.5.27), I come up with errors.
In order to pass the StyleInstance object, I have to use an import statement in my java code:
import org.eclipse.birt.report.engine.script.internal.instance.StyleInstance;
I've done this, and made sure to add the org.eclipse.birt.report.engine_2.5.0.v20081113.jar file to the build path. This works great in the designer, but I get this error in from the apache server:
WARNING: There are errors evaluating script "
printformatter = Packages.com.familyvideo.reportutils.VMCRPrintFormat("report_missing.rptdesign");
":
org/eclipse/birt/report/engine/script/internal/instance/StyleInstance.
org.eclipse.birt.core.exception.CoreException: There are errors evaluating script "
printformatter = Packages.com.familyvideo.reportutils.VMCRPrintFormat("report_missing.rptdesign");
":
org/eclipse/birt/report/engine/script/internal/instance/StyleInstance.
at org.eclipse.birt.core.script.ScriptContext.eval(ScriptContext.java:303)
at org.eclipse.birt.core.script.ScriptContext.eval(ScriptContext.java:331)
at org.eclipse.birt.report.engine.executor.ExecutionContext.evaluate(ExecutionContext.java:653)
at org.eclipse.birt.report.engine.script.internal.ScriptExecutor.handleJSInternal(ScriptExecutor.java:60)
at org.eclipse.birt.report.engine.script.internal.ScriptExecutor.handleJS(ScriptExecutor.java:47)
at org.eclipse.birt.report.engine.script.internal.ReportScriptExecutor.handleBeforeRender(ReportScriptExecutor.java:115)
at org.eclipse.birt.report.engine.api.impl.EngineTask.startRender(EngineTask.java:1355)
at org.eclipse.birt.report.engine.api.impl.RenderTask$PageRangeRender.render(RenderTask.java:509)
at org.eclipse.birt.report.engine.api.impl.RenderTask.render(RenderTask.java:208)
at org.eclipse.birt.report.service.ReportEngineService.renderReport(ReportEngineService.java:1365)
at org.eclipse.birt.report.service.BirtViewerReportService.getPage(BirtViewerReportService.java:202)
at org.eclipse.birt.report.service.actionhandler.AbstractGetPageActionHandler.doExecution(AbstractGetPageActionHandler.java:240)
at org.eclipse.birt.report.service.actionhandler.AbstractGetPageActionHandler.__execute(AbstractGetPageActionHandler.java:107)
... cut down for space.
The jar that I am attaching in the build path is one of BIRT's major pieces, so does anyone have any ideas as to why I can't get tomcat to let me use it in my java class?
Thanks,
Keith
Keith,
You did not put this
org.eclipse.birt.report.engine_2.5.0.v20081113.jar
in the cp for tomcat did you? This is the plugin jar and I would expect it to be available to the event handler without having to do this.
Jason,
I have tried it with and without that jar in the classpath, and it fails both ways.
Maybe this isn't even a BIRT issue, it may be a tomcat issue. Here's my thinking: the jar would be available if it were called directly through the event in the report, but it is called through my custom Java code, and tomcat does not know where to find this jar when it is called in my java code. I had a similar problem with the mysql driver and had to copy the jar in the the apache/common/libs directory to get my scripted data source working in deployment. I tried doing the same with this jar and tomcat started with errors and would only display an error report in my browser when I tried to go to http://localhost:8080/WebViewerExample.
Keith,
Any chance you could email me your event handler (remove client specific logic) let me try on my tomcat instance? If so email it to jasonweathersby at alltel.net.
Jason
toc-level-0[-9] does not appear to have any effect. There are some TOC items on my report I'd really like to style. can I get to these elements with imported css file?
hi, i followed the steps and it doesn't work.
I have a report with a table and want to colour it's rows, based on a css file.
I clicked on "Use CSS", then selected it, got all classes linked.
When i run the report, no visible changes, and styles do not apply to the table, ( i put .table{background-color:gray;}).
I checked the html and no css import on the head.
Then i go to the design, and on the table properties editor/General/Style, and select table.
On the layout, on eclipse, i see the colors, but nothing happens when the report is executed.
Hope you can help.
Thanks in advance,
Diego
Diego,
What version of BIRT are you using?
sr
I am using 2.5.1. When i "Use CSS" files, i can see from the generated HTML that the classes in my css file are imported into the html, but i have another problem.
I have a table, and applied a style, which i Use from my css file. This table isnt taking theese styles because on the generated html it is:
table id="AUTOGENBOOKMARK_2" class="style_2" style="border-collapse: collapse; empty-cells: show; width: 100%; table-layout: fixed; text-align: center;" ...
So it will never take the styles defined in .table (because it's class is "style_2"
I do not really know how to fix this, it seems to be something related to the generation or table config
Thanks in advance
Diego,
If you send the .CSS file and the .rptdesign to scottr (at) innoventsolutions (dot) com and I will take a look.
Also if you can let me know which table is causing the problem.
Is there a way, where I can change the default border-collapse:collapse property from collapse to separate. I am unable to get this working.
Hi,
How can I apply css style only to one element?
For example I have element "label" with name="Title" and id="1"
I tried:
Title{}
#1{}
but both don't work.
Only
.label{}
works, but this rule is apply to all labels. And, again, I want to apply rule only to one element.
Thanks for any tips.
If you want to apply a style to only one label, you want to use a custom style, call it MyLabel.
Create the style and then go to the label in the property editor. The property editor will have a drop down called style. You will be able to select MyLabel from the drop down list.
NOTE: Pre-Defined styles do not show up in the drop-down. (e.g. label is pre-defined name so it won't show in the drop down).
Hi is there way we can have fixed report/table header in BIRT like in excel
Take a look at:
http://www.birt-exchange.org/org/devshare/designing-birt-reports/795-add-a-table-with-a-fixed-header-row/
This sample seems not be working in current version 11sp3. The table header is not fixed. Please share if you have any latest copy.thanks
Are you viewing it just in html? Not in the webviewer? Change the page break interval for the second table from 50 to 0 and then view in html.
Jason
Yes I tried set the second table page break value to 0, and view the report in HTML from Designer ,only I can see the Header.Please correct me if I am missing something.Thanks
That worked for me. What do you mean by the second page break?
As you mentioned Change the page break interval for the second table from 50 to 0 and then view in html. the report has two tables I changed page break interval from 50 to 0 for second table.
Hi i have created a master page for my birt reports in master page i have added a new theme where added a predefined style as table-header-cell where i set a background image for the table header.
This style is working fine once i export my report to PDF or HTML fornmat ,but if i export same report in DOCX format the background iamge is not coming up. Please help i laready waisted 3 days in finding the solution
Post a Comment