How to implement Generate Jasper Report PDF on button click in Liferay Portal 6.1 - pdf

I have a requirement to provide report generation functionality on a button click. I am using Liferay Portal 6.1 with Tomcat 7 as web portal, Liferay Developer Studio (Eclipse Indigo) IDE, iReport (to create report template), and JasperReports library to produce the PDF. The portal is a ticket management system with two entities (Tickets and Documents) which are entered via their respective custom portlets. Both entities, when in edit mode, need the 'View Report' function. I have searched for answers to this problem extensively, picking up a snippet here and there, but nothing I have found is exactly my situation. Upon clicking the 'View Report' button, the user needs to be presented with a formatted PDF where the user can then decide to 'Save', 'Print', or 'Close' from. I also need to pass data to the report so information can be retrieved for the entity that is open (i.e., documentId, ticketId, docType, etc.), but this piece can be added later; once I just get a PDF to open.
Not knowing how to go about implementing this, I decided to use a jQuery Modal to open 'viewReport.jsp' page and process the report there. However, this approach yields a JRException IllegalState: cannot obtain OutputStream because writer is already in use. I have read in my searches that Liferay layout uses OutputStream and that's probably why the writer is already in use. Here's the code I am using:
edit_document.jsp (button and jQuery Modal)
<!-- View Report Button at bottom of form -->
<aui:button type="button" id="viewReportBtn" value="View Report" />
<!-- URL declaration for PDF popup window -->
<portlet:renderURL var="viewReportURL" windowState="<%= LiferayWindowState.EXCLUSIVE.toString() %>" >
<portlet:param name="mvcPath" value="/html/document/viewReport.jsp" />
<portlet:param name="documentId" value="<%= Long.toString(documentID) %>" />
<portlet:param name="ticketId" value="<%= Long.toString(ticketID) %>: />
<portlet:param name="docType" value="<%= docType %>" /> <!-- This is already a String value -->
</portlet:renderURL>
<!-- jQuery to open popup window for PDF -->
<aui:script use="aui-dialog, aui-overlay-manager, dd-constrain" >
var reportDialogOptions = {
title : 'Dialog',
bodyContent : '',
centered : true,
group : default,
height : 800,
width : 1000,
modal : true,
};
$('#viewReportBtn').on('click', finction(event) {
var editFeelingDialog = new A.Dialog(
A.merge(reportDialogOptions, {
title : 'Document View Report'
})
).plugin(A.Plugin.IO,{uri : '<%= viewReportURL %>'}).render();
});
</aui:script>
viewReport.jsp (page to process jrxml template and open PDF)
<!-- viewReport.jsp page to render PDF -->
<%# page contentType = "application/pdf" %>
<%# page trimDirectiveWhitespaces = "true" %>
<%# page import = "net.sf.jasperreports.engine.*" %>
<%# page import = "java.io.File" %>
<%# page import = "java.io.FileInputStream" %>
<%# page import = "java.io.FileNotFoundException" %>
<%# page import = "java.io.InputStream" %>
<%# page import = "java.sql.Connection" %>
<%# page import = "java.sql.SQLException" %>
<%
Connection conn = null;
try
{
String url = "jdbc:oracle:thin:#myDBSRV:1521:myDatabase";
String userName = "myUsername";
String password = "myPassword";
// Connecting to the Oracle database
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url, username, password);
// Loading the Jasper Report file from local file system\
String jrxmlFile = session.getServletContext().getRealPath(request.getContextPath())+"\\report5.jrxml";
InputStream input = new FileInputStream(new File(jrxmlFile));
// Generate the report
JasperReport jasperReport = JasperCompileManager.compileReport(input);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPrint, null, conn);
// Export the report as a PDF
JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
}
catch (FileNotFoundExcecption ex)
{
System.out.println(ex.getMessage());
ex.printStakeTrace();
}
catch (JRException ex)
{
System.out.println(ex.getMessage());
ex.printStakeTrace();
}
catch (ClassNotFoundException ex)
{
System.out.println(ex.getMessage());
ex.printStakeTrace();
}
catch (SQLException ex)
{
System.out.println(ex.getMessage());
ex.printStakeTrace();
}
finally
{
if (conn != null)
{
conn.close();
}
}
%>
I also tried to add java methods to my DocumentPortlet.java class and call the method(s) when the button is clicked, but I am not that familiar enough with ajax to get it right:
DocumentPortlet.java
public class DocumentPortlet extends MVCPortlet{
Connection conn = null;
// More methods for saving, editing, and deleting documents are here...
public void generateReport()
{
initConnection();
showReport();
}
public void initConnection()
{
String host = "jdbc:oracle:thin:#ncimsdbsrv:1521:ncimsdev";
String userName = "lportal";
String password = "NSS4207itnp";
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
}
try
{
conn = DriverManager.getConnection(host, userName, password);
}
catch (SQLException ex)
{
ex.printStackTrace();
}
}
public void showReport()
{
//Path to your .jrxml file
String reportName = "[path to file]";
//Get a stream to read the file
InputStream is = this.getClass().getClassLoader().getResourceAsStream(reportName);
try
{
//Fill the report with parameter, connection, and stream reader
JasperPrint jp = JasperFillManager.fillReport(is, null, session);
//Viewer for Jasper report
JRViewer jv = new JRViewer(jp);
//Insert viewer to a JFrame to make it showable
JFrame jf = new JFrame();
jf.getContentPane().add(jv);
jf.validate();
jf.setVisible(true);
jf.setSize(new Dimension(800, 600));
jf.setLocation(300, 100);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
catch (JRException ex)
{
ex.printStakeTrace();
}
finally
{
closeSession(session);
}
}
}
How can I provide this functionality in a way that my users can click the button and a PDF be generated on their screen? I need a clear and concise solution to this problem. Thank you!
Lee

In case anyone is interested, I found an answer on a Liferay forum. My implementation was not correct. So now I have this in my
viewDocument.jsp:
<!-- View Report button at bottom of form -->
<aui:button id="viewReportBtn" value="View Report" />
<!-- URL declaration for PDF generation -->
<portlet:resourceURL id="generatePDF" var="generateReportURL" >
<portlet:param name="jspPage" value="/html/document/viewReport.jsp" />
<portlet:param name="docType" value="<%= docType %>" />
</portlet:resourceURL>
<!-- AJAX call to resource request handler in DocumentPortlet.java file -->
<aui:script use="aui-dialog, aui-overlay-manager, dd-constrain" >
$(document).ready(function()
{
$('#viewReportBtn').click(function(event)
{
$.ajax('<%= generateReportURL %>');
}
});
I also created the ResourceRequestHandler in my Portlet java file like so:
DocumentPortlet.java:
public class DocumentPortlet extends MVCPortlet{
Connection conn = null;
// More methods to add, update, and delete here
#Override
public void serveResource(ResourceRequest request, ResourceResponse response)
throws IOException, PortletException
{
String url = "jdbc:oracle:thin:#myDatabaseSrv:1521:myDatabaseSid";
String user = "myUserName";
String pass = "myPassword";
String docType = ParamUtil.getString(request, "docType");
try
{
// Connect to database
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url, user, pass);
// Load JRXml file from local file system
String jrxmlFile = "C:\\Reports\\report5.jrxml";
InputStream input = new FileInputStream(new File(jrxmlFile));
// Generate report
JasperReport jasperReport = JasperCompileManager.compileReport(input);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPrint, null, conn);
/***** Display PDF in Adobe Reader *****/
// Create new OutputStream where data is written to byte array[]
ByteArrayOutputStream output = new ByteArrayOutputStream();
// Export the report to PDF format
JasperExportManager.exportReportToPdfStream(jasperPrint, output);
// Create a String for thr report title
final String fileName = docType + ".pdf";
//Create a new stream and call the report
OutputStream pdfFile = new FileOutputStream(new File(fileName));
//Write the PDF
pdfFile.write(output.toByteArray());
//Clean the PDF
pdfFile.flush();
//Close it
pdfFile.close();
//Run the brand new PDF report
final String PDF_RUN = "rundll32 url.dll, FileProtocolHandaler " + fileName;
//Execute the command
Runtime.getRuntime().exec(PDF_RUN);
}
catch(FileNotFoundException ex)
{
System.out.println("File not found on file system, check file path!!" + ex.getMessage());
ex.printStackTrace();
}
catch(JRException ex)
{
System.out.println("Error in Jasper Report!!" + ex.getMessage());
ex.printStackTrace();
}
catch(ClassNotFoundException ex)
{
System.out.println("Oracle Class for driver not found!!" + ex.getMessage());
ex.printStackTrace();
}
catch(SQLException ex)
{
System.out.println("Error getting connection to database!!" + ex.getMessage());
ex.printStackTrace();
}
}
}
This eliminated the IllegalStateException I was getting and will open the pdf in Adobe Reader just fine, however, it opens it up on the server. Therefore, a problem still remains. Anybody know how I can get this pdf to open on the client machine?

Related

Silverlight bingMapContril using LocalproxyPage to downLoad MapTiles Extremely Slow

as we know silverlight5 has ability to get pageElement's visual so we can print or save them as pictrue.but if your MapTilesSource uri is in a differentDomain to your silverlight Application host site,you can not get BingMapControl's visual,because of "cross-domain problem",clr would throw a System.Security.SecurityException.
To avoid this problem I add a Proxy aspx page in the silverlight host site,which can send bingMap TileImage request to the remote MapTilesService.
here is my customer Class inherit from TileSource:
public class GoogleTileSource : TileSource
{
public GoogleTileSource()
: base("http://mt{0}.google.cn/vt/lyrs={1}#180000000&hl=zh-CN&gl=cn&z={2}&x={3}&y={4}")
{
this.Type = GoogleTileType.Hybrid;
}
public override Uri GetUri(int x, int y, int zoomLevel)
{
string TargetUrl = string.Format(this.UriFormat, this.Server, (char)this.Type, zoomLevel, x, y);
return new Uri(string.Format(http://localhost:52879/MapTilesServerProxy.aspx + "?sourceUrl={0}", TargetUrl));
//return new Uri(string.Format(this.UriFormat, this.Server, (char)this.Type, zoomLevel, x, y));
}
public int Server
{
get;
set;
}
public GoogleTileType Type
{
get;
set;
}
}
here is my proxy page code:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="MapTilesServerProxy.aspx.cs" Inherits="AeroZH.Web.MapTilesServerProxy" %>
<%# Import Namespace=System.Net %>
<%# Import Namespace=System.IO %>
<%# Import Namespace=System.Diagnostics %>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ProxyRequest();
}
private void ProxyRequest()
{
try
{
string url = "";
url = this.Page.Request.Url.AbsoluteUri.Split(new string[] { "?sourceUrl=" }, StringSplitOptions.RemoveEmptyEntries)[1];
Debug.WriteLine("url:" + url);
Debug.WriteLine(url + "——requestTime:" + System.DateTime.Now);
HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(url);
loHttp.Timeout = 10000; // 10 secs
loHttp.UserAgent = "Web Client";
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();
Debug.WriteLine(url + "——responseTime:" + System.DateTime.Now);
using (Stream inputStream = loWebResponse.GetResponseStream())
{
byte[] buffer = new byte[4096 * 100];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
} while (bytesRead != 0);
Response.BinaryWrite(buffer);
Response.End();
}
loWebResponse.Close();
if (loHttp != null)
loHttp.Abort();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
after this work,bingMapcontrol successfully make its image request thought the proxy page ,and the ProxyPage's request get response form remote server is also success.but only a few mapTiles show in the map.
I using debug.write to trace response status,almost everyRequest has correct response,i don't know why only few mapTiles show in map.
First off, using Google map tiles in Bing Maps is against the terms of use of both the Bing Maps and Google Maps terms of use.
Secondly, The Bing Maps Silverlight control is nearing end of life. The documentation is already offline and it won't be long before the control is disabled. No new development should be one with it. Also, the end of life for Silverlight in general was announced a few years ago.

How to upload file of p:fileUpload using command button instead of upload button

Iam using JSF2.1 along with primefaces for uploading file.In my application i have to add the file dynamically on creating a record.But when i use
i cant write the code for uploading my file during save.I want the file to be uploaded on click of save only and not during upload.
Can anyone help me how to implement this
public String handleFileUpload(FileUploadEvent event) throws IOException {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
UploadedFile file = event.getFile();
String prefix = FilenameUtils.getBaseName(file.getFileName());
String suffix = FilenameUtils.getExtension(file.getFileName());
String path = "C:/apache-tomcat-7.0.47/webapps/ROOT/WEB-INF/images";
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File fileToDirectory = File.createTempFile(prefix + "-", "." + suffix, new File(path));
InputStream inputStream = event.getFile().getInputstream();
String fileName = event.getFile().getFileName();
OutputStream outputStream = new FileOutputStream(fileToDirectory);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = inputStream.read(buffer)) > 0){
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
return path+fileName;
}
I need to have this code on save but i cant get event during save
That isn't possible with auto mode. Use the basic mode instead. Then you can bind the input value to an UploadedFile property directly. This only requires disabling Ajax.
E.g.
<h:form enctype="multipart/form-data">
...
<p:fileUpload mode="simple" value="#{bean.file}" />
...
<p:commandButton value="Save" action="#{bean.save}" ajax="false" />
</h:form>
with
private UploadedFile file; // +getter+setter
public void save() {
try (InputStream input = file.getInputStream()) {
// ...
}
}
The alternative is to migrate to standard JSF <h:inputFile> component which was introduced in JSF 2.2. Then you can continue using Ajax.
E.g.
<h:form enctype="multipart/form-data">
...
<h:inputFile value="#{bean.file}" />
...
<p:commandButton value="Save" action="#{bean.save}" />
</h:form>
with
private Part file; // +getter+setter
public void save() {
try (InputStream input = file.getInputStream()) {
// ...
}
}
See also:
How to upload file using JSF 2.2 <h:inputFile>? Where is the saved File?

Credentials prompted while rendering a remote ReportViewer control in MVC4

I am creating one web app (mvc 4) to authorize customers (using membership provider) to view the reports(SSRS 2008) for which they are registered but they don't have any kind of access to our report server.
Based on the link How do I render a remote ReportViewer aspx page in MVC4?, I have implemented Elsimer's latest answer and it works well in downloading as a pdf file.
But when I try to render as html using the same code mentioned in the above link it is asking for the windows credentials to access the report server.
So I am giving a general credential which has all access to all the reports in the reportserver through the code. but it is still asking for the credentials for the report server when they try to view as html in the client side browser. Report is getting rendered but the images and graphs are not rendering without credentials.
Please advise, I have tried many things to solve this. but no luck.
My controller and credential class code as follows:
[Route("report/MonthlySummary")]
[ValidateAntiForgeryToken]
public ActionResult MonthlySummary(MonthlyReportParameters model)
{
if (ModelState.IsValid)
{
try
{
var actionType = model.ActionType;
if (actionType == "View Report")
{
return ExportMonthlyReportToHtml(model);
}
else if (actionType == "Download pdf report")
{
return ExportMonthlyReportToPdf(model);
}
}
catch (Exception ex)
{
//Logging errors
}
}
return null;
}
private ActionResult ExportMonthlyReportToHtml(MonthlyReportParameters monthlyParams)
{
ReportViewer reportViewer = BuildMonthlyReport(monthlyParams);
reportViewer.ServerReport.Refresh();
byte[] streamBytes = null;
string mimeType = "";
string encoding = "";
string filenameExtension = "";
string[] streamids = null;
Warning[] warnings = null;
//To view the report in html format
streamBytes = reportViewer.ServerReport.Render("HTML4.0", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
var htmlReport = File(streamBytes, "text/html");
return htmlReport;
}
private static ReportViewer BuildMonthlyReport(MonthlyReportParameters model)
{
ReportViewer reportViewer = new Microsoft.Reporting.WebForms.ReportViewer();
try
{
var rptParameters = new List<ReportParameter>
{
//Building parameters
};
reportViewer.ProcessingMode = ProcessingMode.Remote;
reportViewer.ServerReport.ReportPath = "/reportFolder/reportName";
var reportServerUrl = ConfigurationManager.AppSettings["ReportServerUrl"];
if(!string.IsNullOrEmpty(reportServerUrl))
{
reportViewer.ServerReport.ReportServerUrl = new Uri(reportServerUrl);
}
reportViewer.ServerReport.ReportServerCredentials = new ReportServerCredentials();
reportViewer.ServerReport.SetParameters(rptParameters);
}
catch (Exception ex)
{
var errorMessage = ex.Message;
//TODO: handle errors;
}
return reportViewer;
}
public sealed class ReportServerCredentials : IReportServerCredentials
{
public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
{
authCookie = null;
userName = null;
password = null;
authority = null;
return false;
}
public WindowsIdentity ImpersonationUser
{
get
{
return null;
}
}
public ICredentials NetworkCredentials
{
get
{
string userName = ConfigurationManager.AppSettings["ReportUserName"];
if ((string.IsNullOrEmpty(userName)))
{
throw new Exception("Missing user name from web.config file");
}
string password = ConfigurationManager.AppSettings["ReportPassword"];
if ((string.IsNullOrEmpty(password)))
{
throw new Exception("Missing password from web.config file");
}
string domain = ConfigurationManager.AppSettings["DomainName"];
if ((string.IsNullOrEmpty(domain)))
{
throw new Exception("Missing domain from web.config file");
}
return new NetworkCredential(userName, password, domain);
}
}
}
Thanks in advance,

How to retrieve sql table with all its data using java

I am trying to make a Java EE project with SQL as my database and glassfish as my server.
I want to retrieve all the data in my table in to a html page but I have to use servlet and session beans. My output will be shown in a html page.
An example
<%# page language="java"%>
<%# page import = "java.sql.Connection"%>
<%# page import = "java.sql.DriverManager"%>
<%# page import = "java.sql.ResultSet"%>
<%# page import = "java.sql.Statement"%>
<html>
<body>
<h1>Retrieve data</h1>
<%
try
{
Class.forName("org.gjt.mm.mysql.Driver");
Connection conexion = DriverManager.getConnection("jdbc:mysql://localhost/db", "user", "pass");
if (!conexion.isClosed())
{
Statement st = conexion.createStatement();
ResultSet rs = st.executeQuery("select * from contact");
out.println("<table border=\"1\"><tr><td>Id</td>< td>Name</td><td>LastName</td><td>Phone</td></tr>");
while (rs.next())
{
out.println("<tr>");
out.println("<td>"+rs.getObject("id")+"</td>");
out.println("<td>"+rs.getObject("Name")+"</td>");
out.println("<td>"+rs.getObject("LastName")+"</td>");
out.println("<td>"+rs.getObject("Phone")+"</td>");
out.println("</tr>");
}
out.println("</table>");
conexion.close();
}
else
out.println("fail");
}
catch (Exception e)
{
out.println("Exception " + e);
e.printStackTrace();
}
%>
</body>
</html>

SharePoint 2010

We are working on an assignment to create a web application using SharePoint 2010 which is totally new to all of us.
My challenge is creating a file upload form. I used SharePoint designer to drag the upload texbox and button controls from the ASP.NET tool box. I don't know what to do next because I need the files to go where I want.
Here is the code that I have for the control I palced on the page:
<form id="form1" runat="server">
<asp:FileUpload runat="server" id="FileUpload1" /><br />
<br />
<asp:Button runat="server" Text="Upload" id="Button1" Width="88px" />
</form>
This routine will upload a single file assuming you've implemented the FileUpload control on your page. the routine gets the file name from the FileUpload control and adds it to a SharePoint list:
protected void UploadButton_Click(object sender, EventArgs e)
//=================================================
// upload the file selected in the upload button to the library
//
//=================================================
{
string docLibName = "/documents/Forms/AllItems.aspx";
if (FileUpload.HasFile)
{
try
{
int orderID = Convert.ToInt32(ViewState["OrderID"].ToString());
string status = ddlDocumentStatus.SelectedValue;
string docType = ddlDocumentType.SelectedValue;
// Read the file contents into a byte stream
string filename = FileUpload.FileName;
byte[] contents = new byte[FileUpload.FileContent.Length];
System.IO.Stream myStream;
int fileLen = FileUpload.PostedFile.ContentLength;
myStream = FileUpload.FileContent;
myStream.Read(contents, 0, fileLen);
// Upload the file to "Documents" Library
using (SPSite oSite = new SPSite(_siteURL))
using (SPWeb oWeb = oSite.OpenWeb())
{
docLibName = _siteURL + docLibName;
SPWeb site = new SPSite(docLibName).OpenWeb();
// Copy the file to the sharepoint library
SPFolder myLibrary = oWeb.Folders["Documents"];
// try checking out the file, if it doesn't exist, create it:
SPFile spfile = null;
try
{
spfile = oWeb.GetFile(_siteURL + "/Documents/" + filename);
if (spfile.Exists)
{
spfile.CheckOut();
myLibrary.Files.Add(filename, myStream, true);
}
else // create a new document
{
spfile = myLibrary.Files.Add(filename, myStream, true);
}
SPListItem document = spfile.Item;
// Copy the metadata to the document
//spfile.Item;
// update the metadata for the document here
document["Columns Name"] = some_string_value;
document["Document Type"] = docType;
myLibrary.Update();
document.Update();
spfile.CheckIn("Document updated on " + DateTime.Today.ToString());
}
catch (Exception ex)
{
string errorMessage = ex.Message;
}
// update the sharepoint list
SPList docLib = oWeb.Lists["Documents"];
AddDocuments(orderID, docLib);
lblDocumentMessage.Text = "Document uploaded!";
}// using - Disposes Site and web
}// try
catch (Exception ex)
{
string errorMessage = ex.Message;
lblDocumentMessage.Text = "Document upload error: " + errorMessage;
}
}
}