I am working on extjs 4.0.2a along with Java. I am using some framework with java such as Hibernate/JPA and Spring. Now I want to use a Jasper Report designing tool i.e. iReport to generate my reports in different formats (.xls,.pdf) etc. I am familiar with iReport. I generated the iReport file in .jrxml and .jasper format using the jdbc connection.
Now i want to integrate my generated report with JAVA so I can get the report in either .pdf or .xls format. When I click on pdf icon I can download the report generated in .pdf format.
I am using Ext js 4.0.2a mvc architecture. Anyone having idea how to proceed can help me
My solution for this problem is simple. As you are using ExtJs I think your controller is in JavaScript.
Do a request for the java server to create your report in pdf, xls, whatever
Save the report in your session with a key(can be the time in mileseconds)
Return the key to the view and open a new window to ask the server for your report
The new windows should contain a URL like this http://localhost:8080/myApplication/report?key=312312313
If you want to download to xsl you can try this:
private void exportToExcel(HttpServletResponse resp, JasperPrint jasperPrint) throws IOException {
String reportfilename = tagreport("file") + "repor.xls";
JExcelApiExporter exporterXLS = new JExcelApiExporter();
exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT,jasperPrint);
exporterXLS.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE,Boolean.TRUE);
exporterXLS.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
exporterXLS.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, resp.getOutputStream());
resp.setHeader("Content-Disposition", "inline;filename="+ reportfilename);
resp.setContentType("application/vnd.ms-excel");
try {
exporterXLS.exportReport();
} catch (JRException e) {
e.printStackTrace();
}
}
Related
How can I transform a PDF with forms made in Adobe Livecycle to a simple image PDF using Java?
I tried using Apache PDFBox but it can't save as image a PDF with forms.
This is what I tried(from this question: Convert PDF files to images with PDFBox)
String pdfFilename = "PDForm_1601661791_587488.pdf";
try (PDDocument document = PDDocument.load(new File(pdfFilename))) {
PDFRenderer pdfRenderer = new PDFRenderer(document);
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
ImageIOUtil.writeImage(bim, pdfFilename + "-" + (page+1) + ".png", 300);
}
} catch (IOException ex) {
Logger.getLogger(StartClass.class.getName()).log(Level.SEVERE, null, ex);
}
But is not working, the result is an image where it writes that "The document you are trying to load requires Adobe Reader 8 or higher.
I guess is not possible, I tried many libraries and none worked.
This is how I solved the problem:
I used an external tool - PDFCreator.
In PDFCreator I created a special printer that prints and saves the PDF without asking any questions(you have these options in PDFCreator).
This is simple to reproduce in PDFCreator because in the Debug section you have an option to load a config file, so I have this file prepared, I just install PDFCreator and load the config file.
If you will use my INI file in the link above you should know that the resulted PDF is automatically saved in the folder: "current user folder/Desktop/temporary".
The rest of the job is done from Java using Adobe Reader, the code is in my case:
ProcessBuilder pb = new ProcessBuilder(adobePath, "/t", path+"/"+filename, printerName);
Process p = pb.start();
This code opens my PDF in AdobeReader, prints the PDF to the specified virtual printer, and exists automatically.
"adobePath" is the path to the adobe executable
path+"/"+filename is the path to my PDF.
"printerName" is the name of the virtual printer created in PDFCreator
So this is not a pure Java solution and in the future, I intend to use Apache PDFBox to generate my PDF's in a format that is compatible with browsers and all readers...but this works also.
I am using JasperReport to export a report to a PDF. The code runs fine with no exception messages showing up in the console/log. However, the report does not export to the browser. In other words, the report is being created, I just cannot download or gain access to it.
Here is the export code:
public void generatePDFReport(Map<String, Object> parameters, JRDataSource jrDataSource, String resource, String filename)
{
OutputStream os = null;
try{
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
os = response.getOutputStream();
InputStream reportTemplate = this.getClass().getClassLoader().getResourceAsStream(resource);
byte[] pdf = null;
try {
JasperDesign masterDesign = JRXmlLoader.load(reportTemplate);
masterReport = JasperCompileManager.compileReport(masterDesign);
masterReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
JasperPrint masterPrint = JasperFillManager.fillReport(masterReport, parameters, jrDataSource);
pdf = JasperExportManager.exportReportToPdf(masterPrint);
} catch (JRException e) {
log.error(e);
}
response.setContentType("application/pdf");
response.setContentLength(pdf.length);
response.setHeader("Content-disposition", "attachment; filename=\""+filename+"\"");
context.responseComplete();
os.write(pdf);
pdf = null;
}catch(Exception e){
log.error(e);
}finally{
try{
os.flush();
os.close();
}catch(IOException e){
log.error(e);
}
}
}
I am almost 100% certain that there is nothing wrong with the code as it works fine for different reports (I run the same export code for several other reports and it works as expected for all of them except for this one).
Knowing this, I figured it must have something to do with the report itself. The report is a jrxml JasperReport file. The report was created using iReport. However, I modified the above code to simply save it to the downloads folder and the report is being created perfectly fine.
So, the problem is that the report is successfully being created in the backend but it is not being sent to the front-end (browser) as expected.
I am open to any suggestions as to why this report would not be working.
Running the code inside a bean is problematic because:
only one call to getOutputStream is allowed per HTTP request
the web framework (J2EE/JSF) has likely already written HTTP headers
the JSF page has likely already been written as HTML inside a temporary buffer (flushed upon calling responseComplete()).
the headers could be reset, but that won't help with the getOutputStream issue
calling responseComplete() flushes any HTML along with PDF content to the browser
Use a servlet. The send method of the servlet needn't be any more complex than:
protected void send(final byte[] content) throws IOException {
setContentLength(content.length);
try (final OutputStream out = getOutputStream()) {
out.write(content);
}
}
Also consider setting the cache so that stale reports are not possible:
protected void disableCache() {
// https://tools.ietf.org/html/rfc7234#section-7.1.3
setHeader(CACHE_CONTROL, "private, no-store, no-cache, must-revalidate");
// https://tools.ietf.org/html/rfc7234#section-5.3
setHeader(EXPIRES, "Thu, 01 Dec 1994 16:00:00 GMT");
// https://tools.ietf.org/html/rfc7234#section-5.4
setHeader(PRAGMA, "no-cache");
// https://tools.ietf.org/html/rfc7232#section-2.2
setHeader(LAST_MODIFIED, getServerTimestamp());
}
private String getServerTimestamp() {
final SimpleDateFormat rfc1123 = new SimpleDateFormat(DATE_RFC_1123, getDefault());
rfc1123.setTimeZone(getTimeZone("GMT"));
final Calendar calendar = Calendar.getInstance();
return rfc1123.format(calendar.getTime());
}
This implies, for example:
#WebServlet(
name = "ReportServlet",
urlPatterns = {PATH_SERVLET + "ReportServlet"}
)
public class ReportServlet extends AbstractServlet {
}
And then use a regular anchor link:
<h:outputLink value="/app/path/servlet/Reportservlet">Run Report</h:outputLink>
In summary, don't send binary report data by intercepting a request to a JSF page; use a servlet, instead.
Communications between servlets and JSF pages can be made via:
Session variables (HTTPSession on the servlet side)
URL parameters
Servlets have the advantage that the JSF overhead is completely avoided, which will make the report run faster from the user's perspective. Also, don't compile the report -- use the .jasper file directly, which will also have performance improvements. (I did not mean to imply using the .jrxml file was the problem, merely that it isn't a necessary step.)
I figured out a solution to my problem. Ultimately, I found that there was nothing wrong with the report generation code or the reports, but there was an ajax issue that was preventing the outputstream from exporting the report to the browser.
I created an jrxml file using iReport Designer tool. It works nice in iReport Designer tool. Now I am trying to compile that jrxml file using a Java program. The MySQL query is there in the jrxml file. I think the jrxml file is okay since it works as expected in iReport Designer tool.
When I run my Java program to compile and generate a PDF file of a report with JREmptyDataSource, it generates a pdf without any data filled, but the graphics ans static texts are there in the generated pdf. I know there is no data since I used a JREmptyDataSource.
Then I created a connection to my database. If things are okay, it should generate the PDF file with relevant data. Isn't it?
This is my code
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/my_db", "root", "123");
System.out.println("INFO: Connected succesfully to the database!");
JasperReport jasperReport = JasperCompileManager.compileReport("J:/reports using iReport tools/installmentListForACustomer.jrxml");
// JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,new HashMap(), new JREmptyDataSource());
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,new HashMap(), c);
JasperExportManager.exportReportToPdfFile(jasperPrint, "fromXml.pdf");
System.out.println("INFO: Success!");
} catch (Exception e) {
System.out.println("EXCEPTION: " + e + " \n");
e.printStackTrace();
}
But the issue is, even though it generates a pdf file, it contains nothing. Not even the static texts and graphics. it is complete blank.
Query string is in the jrxml file. Database connection is successful as well. I cannot figure out why it generates an empty PDF.
Could you please explain to me why doesn't it generate a pdf file with relevant in database?
There is a report configuration which may be an issue in your example:
When No Data
You can specifiy what your report should show when there is no data available. This could be one explanation (your query may don't work) and so nothing is displayed.
To check this you can try enter When no Data = No Data Section and add a "No Data" band in your report.
I have learned that JasperViewer (default preview component of JasperReports) is a Swing component, so is there any way to convert or embed it in a web application? Some say I should use Java Web Start, but from what i have learned from this link JWS is useful to download and install an application on client machine and this is not our case. the other work around that it may work (maybe just in theory) is converting jFrame to jApplet as briefly described in this link
Have you tried any of these solutions and did they work?
Do you know any other solution to this problem?
If you know how to generate a report, you can easily do it inside a servlet and send the generated file to the client. Using a JWS application or an Applet would most likely mean that the report is generated client-side and that the raw data plus all the dependencies are also available to the client.
The code below assumes that you're generating a PDF file
public class ReportServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
// initialize your report objects here
JasperReport jasperReport =
JasperPrint print =
JRPdfExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, resp.getOutputStream());
resp.setContentType("application/pdf");
exporter.exportReport();
} catch (Exception e) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error generating report : " + e.getClass() + " " + e.getMessage());
}
}
You can extend the example above to support multiple export formats by setting the correct content type and using the matching JRXYZExporter (JRHtmlExporter, JExcelApiExporter,...)
If you need something more customizable, you might also want to look into Jasper Server
i am developing cloud application which is hosted on google app engine and in this i want to generate excel file on click of button through servlet.
i have done it on local machine but when i deploy my application on app engine it shows error HTTP Error 500 Internal server error
i am using jxl java api for generating excel file
code that i have used is here
try
{
//i have used following content type but didn't worked.....
//response.setContentType("application/CSV");
//response.setContentType("application/x-ms-excel");
response.setContentType("application/vnd.ms-excel");
WritableWorkbook w = Workbook.createWorkbook(response.getOutputStream());
WritableSheet s = w.createSheet("Demo", 0);
Label label = new Label(0, 2, "A label record");
s.addCell(label);
w.write();
w.close();
}
catch (Exception e)
{
response.getOutputStream().println("Exception :"+e);
}
finally
{
}
I have used some code like this in the past to export CSV:
response.setHeader("Cache-Control", "");
response.setHeader("Pragma", "");
response.setHeader("Content-Disposition", "attachment; filename=foo.csv");
response.setContentType("text/csv");
What is the output of the println statement?
You are in trouble anyway though because as far as I can see, you can't use external libraries on Google App engine (and I don't think they have included that particular service).