How to edit jasper file? - java

I am editing .jasper file using report tool. I am changing the alignment for parameter left to centre then i save that file. it generates the "jrxml" file also. in my Java code I can pass the .jasper location to print some items. but my changes not affect and the old design remains same..
Help me , How can I edit and save .jasper???
public static JasperPrint createRefundPrint(Ticket ticket, HashMap map) throws Exception {
final String FILE_RECEIPT_REPORT = "/com/floreantpos/report/template/RefundReceipt.jasper";
TicketDataSource dataSource = new TicketDataSource(ticket);
return createJasperPrint(FILE_RECEIPT_REPORT, map, new JRTableModelDataSource(dataSource));
}

if you use a IReport for editing your .jrxml reports, you should just press the "Preview" button. Then the .jasper report file will be generated automatically in folder that contains the .jrxml file

To edit jasper report, you make your changes in the JRXML file. Once you build or compile your report it will generate a .jasper file which is used in your java code.

you try make dynamic report.
You do not have a location problem when you generate your own report.
Example;
public JasperDesign createDesign() throws JRException {
JasperDesign jasperDesign = new JasperDesign();
jasperDesign.setName("sampleDynamicJasperDesign");
jasperDesign.setPageWidth(595); // page width
jasperDesign.setPageHeight(842); // page height
jasperDesign.setColumnWidth(515); // column width of page
jasperDesign.setColumnSpacing(0);
jasperDesign.setLeftMargin(40);
jasperDesign.setRightMargin(40);
jasperDesign.setTopMargin(20);
jasperDesign.setBottomMargin(20);
JRDesignExpression expression = new JRDesignExpression();
//Set style of page.
JRDesignStyle normalStyle = new JRDesignStyle();
normalStyle.setName("Sans_Normal");
normalStyle.setDefault(true);
normalStyle.setFontName("DejaVu Sans");
normalStyle.setFontSize(12);
normalStyle.setPdfFontName("Helvetica");
normalStyle.setPdfEncoding("Cp1252");
normalStyle.setPdfEmbedded(false);
jasperDesign.addStyle(normalStyle);
/*
* Generate field dynamically
* */
JRDesignField field = new JRDesignField();
field.setName("firstName");
field.setValueClass(String.class);
jasperDesign.addField(field);
field = new JRDesignField();
field.setName("lastName"); // set name for field.
field.setValueClass(String.class); // set class for field. Its always depends upon data type which we want to get in this field.
jasperDesign.addField(field); // Added field in design.
field = new JRDesignField();
field.setName("age");
field.setValueClass(Integer.class);
jasperDesign.addField(field);
JRDesignBand band = new JRDesignBand();
//Title Band
band = new JRDesignBand();
band.setHeight(30);
JRDesignStaticText staticText = new JRDesignStaticText();
staticText.setText("Person's Specification");
staticText.setX(0);
staticText.setY(0);
staticText.setHeight(20);
staticText.setWidth(515);
staticText.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
band.addElement(staticText);
jasperDesign.setTitle(band);
band = new JRDesignBand(); // New band
band.setHeight(20); // Set band height
/*Create text field dynamically*/
JRDesignTextField textField = new JRDesignTextField();
textField.setX(0); // x position of text field.
textField.setY(0); // y position of text field.
textField.setWidth(160); // set width of text field.
textField.setHeight(20); // set height of text field.
JRDesignExpression jrExpression = new JRDesignExpression(); // new instanse of expression. We need create new instance always when need to set expression.
jrExpression.setText(""" + "First Name: " + """ + "+" + "$F{firstName}"); // Added String before field in expression.
textField.setExpression(jrExpression); // set expression value in textfield.
band.addElement(textField); // Added element in textfield.
textField = new JRDesignTextField();
textField.setX(160);
textField.setY(0);
textField.setWidth(160);
textField.setHeight(20);
jrExpression = new JRDesignExpression();
jrExpression.setText("$F{lastName}" + "+" + """ + " :Last Name" + """); // Added string after field value
textField.setExpression(jrExpression);
band.addElement(textField);
textField = new JRDesignTextField();
textField.setX(320);
textField.setY(0);
textField.setWidth(160);
textField.setHeight(20);
jrExpression = new JRDesignExpression();
String age = """ + "<font>" + """ + "+" + """ + "Age is: " + """ + "+" + """ + "</font><font>" + """ + "+" + "$F{age}" + "+" + """ + "</font>" + """; // added html in text field with different color.
jrExpression.setText(age);
textField.setExpression(jrExpression);
textField.setMarkup("html"); // By Default markup is none, We need to set it as html if we set expression as html.
band.addElement(textField);
((JRDesignSection) jasperDesign.getDetailSection()).addBand(band);
return jasperDesign;
}

You can compile a .jrxml in Project Explorer window of Jaspersoft Studio. For that first find your .jrxml report and rightclick on it. In context menu choose 'Compile report'. Then you get compiled .jasper report.

Related

In Excel file , How to set cell name using Java

I have an excel file. I want to set a unique name to a particular cell.
But there is no method called "cell.setName".
Regarding official documentation:
Named Range is a way to refer to a group of cells by a name. Named Cell is a degenerate case of Named Range in that the 'group of cells' contains exactly one cell. You can create as well as refer to cells in a workbook by their named range. When working with Named Ranges, the classes org.apache.poi.ss.util.CellReference and org.apache.poi.ss.util.AreaReference are used.
Note: Using relative values like 'A1:B1' can lead to unexpected moving of the cell that the name points to when working with the workbook in Microsoft Excel, usually using absolute references like '$A$1:$B$1' avoids this, see also this discussion.
Creating Named Range / Named Cell
// setup code
String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet(sname);
sheet.createRow(0).createCell(0).setCellValue(cvalue);
// 1. create named range for a single cell using areareference
Name namedCell = wb.createName();
namedCell.setNameName(cname + "1");
String reference = sname+"!$A$1:$A$1"; // area reference
namedCell.setRefersToFormula(reference);
// 2. create named range for a single cell using cellreference
Name namedCel2 = wb.createName();
namedCel2.setNameName(cname + "2");
reference = sname+"!$A$1"; // cell reference
namedCel2.setRefersToFormula(reference);
// 3. create named range for an area using AreaReference
Name namedCel3 = wb.createName();
namedCel3.setNameName(cname + "3");
reference = sname+"!$A$1:$C$5"; // area reference
namedCel3.setRefersToFormula(reference);
// 4. create named formula
Name namedCel4 = wb.createName();
namedCel4.setNameName("my_sum");
namedCel4.setRefersToFormula("SUM(" + sname + "!$I$2:$I$6)");
Link: https://poi.apache.org/components/spreadsheet/quick-guide.html#NamedRanges
// setup code
String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet(sname);
sheet.createRow(0).createCell((short) 0).setCellValue(cvalue);
// 1. create named range for a single cell using areareference
Name namedCell = wb.createName();
namedCell.setNameName(cname);
String reference = sname+"!A1:A1"; // area reference
namedCell.setRefersToFormula(reference);
From : http://poi.apache.org/components/spreadsheet/quick-guide.html#NamedRanges

Apache POI PPT (Java) - Updating TextShape keeping text formatting/shape formatting

I am trying to produce several reports (i.e. N PPTX files) based on different inputs/for different users on the same PPTX template I created.
I have several preformatted XSLFTextShape on the PPTX template that contains a single XSLFTextParagraph already formatted (i.e. both the shape and the text). Each shape contains a particular placeholder that I need to substitute with a dynimic value. I have this value in a Map (placeholder,newValue). I am successful in updating the placeholder with the new value using:
textShape.clearText();
XSLFTextRun run = paragraph.addNewTextRun();
run.setText(newText);
So, when I produce the PPTX in output the text is updated but font color, font formatting, font size are changed compared to those I defined in the template. How can I keep the same formatting?
Any solutions to simply change the text while keeping original formatting?
Thanks in advance!
For everybody which may be interested in this topic in the future - I post the solution (working if one TextBox has a single Paragraph). This solution loops on all text boxes and in the case one contain one of the vales specified in the Placeholder->newValue map, it will update it maintaining the formatting.
public static void updateTextBoxesWithDesiredValues(XMLSlideShow ppt, Map<String, String> placeHolderDefinedValue) {
logger.info("ElapsedTime: " + tM.getTimeElapsedReadableFormat() + " ########## Updating single text box content...");
List<XSLFSlide> allSlides = ppt.getSlides();
int updatedElements = 0;
for (XSLFSlide currentSlide : allSlides) {
for (XSLFShape shape : currentSlide.getShapes()) {
if (shape instanceof XSLFTextShape) {
XSLFTextShape textBox = (XSLFTextShape) shape;
String elementTextContent = textBox.getText();
for (Object key : placeHolderDefinedValue.keySet()) {
if (elementTextContent.equals(key)) {
List<XSLFTextParagraph> textBoxParagraphs = textBox.getTextParagraphs();
List<XSLFTextRun> textBoxParagraphTextRuns = textBoxParagraphs.get(0).getTextRuns();
//System.out.println("########################## check paragraph number in textbox: " + textBoxParagraphs.size() + " - TextRuns: " + textBoxParagraphs.get(0).getTextRuns().size());
logger.info("ElapsedTime: " + tM.getTimeElapsedReadableFormat() + updatedElements + ") Updating: " + textBox.getText() + " --> " + placeHolderDefinedValue.get(key));
for (XSLFTextRun r : textBoxParagraphTextRuns) {
r.setText(placeHolderDefinedValue.get(key));
}
updatedElements++;
//break;
}
}
}
}
}
logger.info("ElapsedTime: " + tM.getTimeElapsedReadableFormat() + " Total Text Element Content Updated: " + updatedElements + " #########################");
}
It's kind of horrible - but yeah there's a reason they called it "POI".
Here's my approach to "only reset text" of an existing XSLFTextShape (that must have at least some text pre-set!):
textShape.getTextParagraphs().get(0).getTextRuns().get(0).setText(text);
for (int i = 1; i < textShape.getTextParagraphs().get(0).getTextRuns().size(); i++) {
textShape.getTextParagraphs().get(0).getTextRuns().get(i).setText("");
}
for (int i = 1; i < textShape.getTextParagraphs().size(); i++) {
textShape.getTextParagraphs().get(i).getTextRuns().stream().filter(tr -> !tr.getRawText().equals("\n")).forEach(tr -> tr.setText(""));
}
It will replace all existing text(paragraphs/runs) with "empty" text, but linebreaks can't be replaced for some reason. So this might leave you with some trailing lines - as they usually(!) are transparent this won't really hurt a lot.
.clearText / removing paragraphs either destoyed the formatting for me, or didn't work. Trying to reset the style (fontColor, fontFamily, fontSize, isBold, isItalit, ...) didn't result in satisfying results :(

HTML code in Dynamic jasper

I tried to add an HTML styled text to my dynamic jasper report
JRDesignBand band = new JRDesignBand();
band.setHeight(20); // Set band height
JasperDesign jasperDesign = new JasperDesign();
JRDesignTextField textField = new JRDesignTextField();
textField.setX(0); // x position of text field.
textField.setY(0); // y position of text field.
textField.setWidth(860); // set width of text field.
textField.setHeight(20); // set height of text field.
JRDesignExpression jrExpression = new JRDesignExpression(); // new instanse of expression. We need create new instance always when need to set expression.
jrExpression.setText("<p>text space</p>"); // Added String before field in expression.
textField.setExpression(jrExpression);
textField.setMarkup("html");
band.addElement(textField);
((JRDesignSection) jasperDesign.getDetailSection()).addBand(band);
JasperDesignViewer.viewReportDesign(jasperDesign);
But the text still has HTML tags.
As far as I know, the html tags allowed are very limited and for basic text formatting.
<b>bold</b>
<i>italic</i>
<u>underlined</u>
And thats it.
There is a discussion here about "html" and "styled" markup having issues when exporting to PDF http://community.jaspersoft.com/questions/521757/html-markup-pdf

How to retrive a report variable from java code, to check if report has no pages?

Could anyone explain how to retrieve the REPORT_COUNT variable value of a report from my java code?.
I need that value because I want to show my own message when report has no pages and I don't want to show empty viewer in that case.
Your asking how to get report variable and this is how:
//Create a base filler
JRBaseFiller filler = JRFiller.createFiller(DefaultJasperReportsContext.getInstance(),report);
//Fill the report
JasperPrint jasperPrint = filler.fill(map, connection);
//Get the variables / parameter from the filler
Object rc = filler.getVariableValue("REPORT_COUNT");
int count = 0;
if (rc instanceof Number){
count = ((Number)rc).intValue();
}
However, the easiest way to check if you have pages is this:
Set the attribute whenNoDataType="NoPages" on the jasperReport tag in the jrxml. This attribute will ensure that empty report (0 pages) is returned if your datasource is empty. (see whenNoDataType attributes)
and in java.
//jasperPrint is the JasperPrint object retrieved after fill
List<JRPrintPage> pages = jasperPrint.getPages();
if (pages.size() == 0) {
// No pages
}

JasperReportBuilder HTML row height

I am building a report with JasperReportBuilder from a JDBC data source and afterward I export it to HTML by calling the toHtml method with a JasperHtmlExporterBuilder object parameter. I have been trying to get rid of extra space that exists above the text in each of my rows, column header row, and even my title. I have tried everything I can think of and have been searching online to no avail.
It seems most people have the opposite problem: they need to grow their rows to fit their text. I would like to force my rows to be the height of their contents. If that's not possible, I would be happy with restricting the height of my rows.
The HTML exporter appears to be controlling the height of my rows by inserting an image and setting its height.
Any help would be appreciated. Thanks!
Edit: Here is my code.
String imageServletUrl = "images?image=";
StringWriter writer = new StringWriter();
JasperHtmlExporterBuilder htmlExporter = Exporters.htmlExporter(writer);
htmlExporter.setImagesURI(imageServletUrl);
SqlRowSet rowSet = getData(databaseIpAddr, portNumber, databaseName, databaseUser, databasePassword);
JRDataSource ds = createDataSource(rowSet);
JasperReportBuilder builder = DynamicReports.report();
IntegerType intType = DynamicReports.type.integerType();
DateType dateType = DynamicReports.type.dateType();
int rowHeightPx = 20;
TextColumnBuilder<Integer> col1 = col
.column(COL_TITLE_RESULT_NUM, RESULTS_COL_TITLE_RESULT_NUM, intType)
.setWidth(35)
.setFixedHeight(rowHeightPx)
.setStretchWithOverflow(true);
... create other eight columns ...
StyleBuilder titleStyle = stl.style()
.bold()
.setFontSize(22)
.setHorizontalAlignment(HorizontalAlignment.CENTER);
StyleBuilder columnTitleStyle = stl.style()
.bold()
.setAlignment(HorizontalAlignment.CENTER, VerticalAlignment.MIDDLE)
.setBorder(stl.pen1Point());
StyleBuilder columnStyle = stl.style()
.setAlignment(HorizontalAlignment.CENTER, VerticalAlignment.MIDDLE)
.setLineSpacing(LineSpacing.SINGLE)
.setBorder(stl.pen1Point());
TextFieldBuilder<String> titleBuilder = DynamicReports.cmp
.text(selectedAgency)
.setStyle(titleStyle)
.setFixedHeight(20);
TextFieldBuilder<String> subtitleBuilder = DynamicReports.cmp
.text("Start Time: " + startDate + " " + getStartTime() + ", End Time: " + endDate + " " + getEndTime())
.setFixedHeight(20);
TextFieldBuilder<String> noDataMsgBuilder = DynamicReports.cmp
.text(NO_DATA_MSG)
.setStyle(columnStyle);
builder
.title(titleBuilder)
.addPageHeader(subtitleBuilder)
.setColumnTitleStyle(columnTitleStyle)
.columns(col1, col2, col3, col4, col5, col6, col7, col8, col9)
.setColumnStyle(columnStyle)
.highlightDetailOddRows()
.noData(titleBuilder, subtitleBuilder, noDataMsgBuilder)
.setWhenNoDataType(WhenNoDataType.NO_DATA_SECTION);
String reportHtml;
try {
// this seems to be required to get to the DynamicReports images
getContext().getRequest().getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, builder.toJasperPrint());
builder.toHtml(htmlExporter);
reportHtml = writer.toString();
}
catch (DRException e)
{
e.printStackTrace();
reportHtml = "There was an error generating the report";
}
Edit: Below solution works fine only with DynamicJasper library rather than DynamicReports. There must be similar operations in DR API as well i believe (not sure though - my exposure with DR is only very limitted :().
A combination of DynamicReportBuilder::setHeaderHeight(..), setDetailHeight(..) and JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN parameter setting must do it?
// build dynamicreport instance
DynamicReportBuilder dynamicReportBuilder = new DynamicReportBuilder();
dynamicReportBuilder.setHeaderHeight(50); //sets the column header height
dynamicReportBuilder.setDetailHeight(50); //sets the detail band rows height
DynamicReport dynamicReport = dynamicReportBuilder.build();
// build jasperprint..
JasperPrint jasperPrint = DynamicJasperHelper.generateJasperPrint(
dynamicReport, new ClassicLayoutManager(), dataSource, new HashMap<String, Object>());
// export as html
JRExporter exporter = new JRHtmlExporter();
// tell jasper not to use images for aligning
exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, targetFile);
exporter.exportReport();
adapt reports band heigts to heigth of your row for each band, make sure that you dont have any emty spaces between your rows. If you want to have "emty row" create an emty text field with width of the corresponding band. Think about the report as about grid.

Categories