I need to read an Excel file and display its content.
I have a backing bean code which reads a particular Excel file and displays its content in the console. I have to display the contents inside a text editor. Using PrimeFaces I have got the <p:fileUpload> and <p:editor>.
Here's the bean:
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public String convertjava(String b) {
try
{
FileInputStream file = new FileInputStream(new File(""));
// Get the workbook instance for XLS file
HSSFWorkbook workbook = new HSSFWorkbook(file);
// Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);
// Iterate through each rows from first sheet
Iterator<Row> rowIterator = sheet.rowIterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
// For each row, iterate through each columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_NUMERIC:
cell.getNumericCellValue();
break;
case Cell.CELL_TYPE_STRING:
cell.getStringCellValue();
break;
}
}
System.out.println("");
}
file.close();
FileOutputStream out = new FileOutputStream(new File(""));
workbook.write(out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("error");
}
}
Here's the Facelet:
<h:body>
<h:form enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{uploadBean.handleFileUpload}"
mode="advanced" update="display" auto="true" sizeLimit="10000000"
allowTypes="/(\.|\/)(xls|xlsx)$/" />
<p:growl id="display" showDetail="true" />
<h:commandButton action="#{uploadBean.convertjava}"
value="Excel Report" />
</h:form>
<br />
</h:body>
Here I am totally blank that how to call that convertJava() method through JSF tags and display the read excel values inside an text editor.
You should get hold of the uploaded file in the file upload listener method. You are currently nowhere doing that. You're basically completely ignoring the uploaded file. This makes indeed no sense.
Assign it as a property of the (view scoped) bean as follows:
private UploadedFile uploadedFile;
public void handleFileUpload(FileUploadEvent event) {
uploadedFile = event.getFile();
// ...
}
Then just feed its InputStream to HSSFWorkbook constructor. You're currently attempting to read a non-existing file. This makes indeed no sense. You should be reading the uploaded file. Replace the nonsensicial
FileInputStream file = new FileInputStream(new File(""));
HSSFWorkbook workbook = new HSSFWorkbook(file);
// ...
by
InputStream input = uploadedFile.getInputStream();
HSSFWorkbook workbook = new HSSFWorkbook(input);
// ...
By the way, inside the loop over the Excel cells, you're also nowhere assigning the found data to a property/variable. All with all, it seems that your root mistake is that you keep ignoring values provided to you instead of assigning them to variables for later reuse/redisplay. This problem is in turn not exactly related to JSF, but just to basic Java. Therefore I recommend to take a JSF pause and make an effort of learning basic Java.
Related
Sorry for my poor english but I really want to show two pdf reports from jasper report at the same time in differents tabs on browser. I´m working with java jsf, primefaces. The principal idea is when the button is clicked show this reports in diferents tabs. I try to do this:
I have this in the Managed Bean:
public void showReports() {
RequestContext.getCurrentInstance().execute("document.getElementById('fromGeneral:rep2').click();");
RequestContext.getCurrentInstance().execute("document.getElementById('fromGeneral:rep3').click();");
}
public void printReport(String name) {
try {
Map<String, Object> mapParametros = new HashMap<>();
mapParametros.put("CORR", corr);
printJasper(mapParametros, new File("/Jasper/Reports/" + name));
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void printJasper(Map<String, Object> reportValues, File fileJ) {
ByteArrayInputStream input = null;
BufferedOutputStream output = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
try {
facesContext = FacesContext.getCurrentInstance();
externalContext = facesContext.getExternalContext();
response = (HttpServletResponse) externalContext.getResponse();
FileInputStream file = new FileInputStream(fileJ);
JasperReport compiledTemplate = (JasperReport) JRLoader.loadObject(file);
ByteArrayOutputStream out = new ByteArrayOutputStream();
JasperPrint jasperPrint = JasperFillManager.fillReport(compiledTemplate, reportValues, dataSourceP.getConnection());
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out);
exporter.setParameter(JRPdfExporterParameter.PDF_JAVASCRIPT, "this.print();");
exporter.exportReport();
input = new ByteArrayInputStream(out.toByteArray());
response.reset();
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Length", String.valueOf(out.toByteArray().length));
response.setHeader("Content-Disposition", "inline; filename=\"ticket.pdf\"");
output = new BufferedOutputStream(response.getOutputStream(), Constants.DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[Constants.DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
} catch (Exception exception) {
System.out.println(exception.getMessage());
} finally {
try {
if (output != null) {
output.close();
}
if (input != null) {
input.close();
}
} catch (Exception exception) {
/* ... */
}
}
facesContext.responseComplete();
}
An this in my view:
<h:form>
<p:commandButton value="Show them" action="#{reportBean.showReports()}"/>
<p:commandButton value="REPORT 1" id="rep1" style="font-size: 25px; float:right;visibility: hidden;" action="#{reportBean.printReport("Report1")}" ajax="false" onclick="this.form.target = '_blank';"/>
<p:commandButton value="REPORT 2" id="rep2" style="font-size: 25px; float:right;visibility: hidden;" action="#{reportBean.printReport("Report2")}" ajax="false" onclick="this.form.target = '_blank';"/>
</h:form>
But doesn´t work, it just show the second report.
Help!.
Thanks!
Try a hit using p:commandLink like i am using.
<p:commandLink id="PreviewR1" value="Print Preview" ajax="false" action="#{reportBean.printReport("Report1")}" target="_blank" />
<p:commandLink id="PreviewR2" value="Print Preview" ajax="false" action="#{reportBean.printReport("Report2")}" target="_blank" />
It will open the report 1 & 2 in separate browser tab while your original web page will remains the same.
You just don't click the correct buttons:
public void showReports() {
RequestContext.getCurrentInstance().execute("document.getElementById('fromGeneral:rep2').click();");
RequestContext.getCurrentInstance().execute("document.getElementById('fromGeneral:rep3').click();");
}
You're clicking on rep2 and rep3. rep3 doesn't exists, you need to click on rep1 instead. That should be the reason why only the 2nd report is shown.
Finally I found other way to solve it.
The method showReports() instead to click two buttons, this open two xhtml that each one has inside of <h.form> a remotecommand with autorun true, that show the reports. I don´t know if it´s the best way to do it, but It works.
Thanks for all your comments
I have created Pdf file on click action of Print button using Apache PDFBox api as shown below. As of now I saved that file into my drive(file system). What I need is to open up Pdf file directly into browser without saving into drive so that it can be print or download as require.
TestPdfBean.java
#ManagedBean(name = "pdfBean")
#ViewScoped
public class TestPdfBean implements Serializable {
public void createAndOpenPdf() {
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDFont font = PDType1Font.HELVETICA;
PDPageContentStream content = new PDPageContentStream(doc,page);
content.beginText();
content.setFont(font, 12);
content.moveTextPositionByAmount(100, 700);
content.drawString(" Generating Pdf content...");
content.endText();
content.close();
document.save("/home/ck/Test/test.pdf");
document.close();
}
}
Code snippet of test.xhtml
<h:form id="pdfForm">
<p:panelGrid columns="2">
<h:outputText value="Create Pdf file.." />
<p:commandButton value="Print" actionListener="#{pdfBean.createAndOpenPdf}" />
</p:panelGrid>
</h:form>
I have deployed above portlet into liferay-portal-6.1.1.
Is there any way to open up pdf file directly into browser by Primefaces Or by Jsf Or by Liferay ?
I would recommend that you take a look at the Liferay Faces jsf2-export-pdf-portlet demo for Liferay 6.1. It has an example of a JSF 2.x ResourceHandler that enables the PDF to be generated and downloaded.
Create an HttpServlet and give back the PDF in the response.
Then just link your commandButton to the URL of the servlet and you´re done ...
The browser will open the document if you return a ByteArrayOutputStream.
`FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachement;filename=Quote_.pdf");
response.encodeRedirectURL("_blank");
byte[] bytes = printPDFBean.createQuotationPDF(current, cfgDoc, cfgEntity, quoteDetailList, customer).toByteArray();
response.getOutputStream().write(bytes);
context.responseComplete();`
This code calls my createQuotationPDF method which returns ByteArrayOutputStream object. The issue is, the document is opened in the current window and not a new one.
`public ByteArrayOutputStream createQuotationPDF(Quotation currentQuote, CfgDoc cfgDoc, CfgEntity cfgEntity, List<QuotationDetail> quoteDetailList, Customer customer) {
String filePath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
String imagesFolder = filePath + FacesContext.getCurrentInstance().getExternalContext().getInitParameter("smefin.images");
String fontsFolder = filePath + FacesContext.getCurrentInstance().getExternalContext().getInitParameter("smefin.fonts");
PDDocument doc = null;
PDPage page = null;
ByteArrayOutputStream output;
output = new ByteArrayOutputStream();
try {
doc = new PDDocument();
page = new PDPage();
doc.addPage(page);
File fontLatoBlackFile = new File(fontsFolder + "Lato-Black.ttf");
File fontLatoLiteFile = new File(fontsFolder + "Lato-Light.ttf");
Encoding encoding = new WinAnsiEncoding();
PDFont fontLatoBold = PDTrueTypeFont.load(doc, fontLatoBlackFile, encoding);
PDFont fontLatoLite = PDTrueTypeFont.load(doc, fontLatoLiteFile, encoding);
content.beginText();
content.setFont(fontLatoBold, 11);
content.newLineAtOffset(50, 60);
content.showText("Text");
content.endText();
}
doc.save("D:/TestData/Quote_.pdf");
doc.close();
} catch (Exception e) {
System.out.println("" + e);
}
return output;
}`
i want to know if there is a possibility in JSF or primefaces that allow to input all values of a column( from excel for example ) on a JSF page and submit it to the managed bean. thats mean getting the values in a list in the managed bean .
i designed this figure to let youunderstand what i mean :
Do you have an idea how we can do that ?
Yes, there is a possibility. Here are the necessary steps involved.
Upload an Excel file by using, for example, <p:fileUpload> component:
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{bean.file}" mode="simple"/>
<p:commandButton value="Submit" ajax="false" action="#{bean.upload}"/>
</h:form>
and
public class Bean {
private UploadedFile file;//getter + setter
private List<String> data;//placeholder
public void upload() {
if(file != null) {
extractData(file.getInputstream);
}
}
}
Read the file contents in extractData method by using, for example, Apache POI library:
private void extractData(InputStream is) {
HSSFWorkbook workbook = new HSSFWorkbook(is);
HSSFSheet sheet = workbook.getSheetAt(0);
List<String> data = new ArrayList<String>();
for(Row row : sheet) {
Cell cell = r.getCell(0, Row.RETURN_BLANK_AS_NULL);
if(c != null) {
String content = cell.getStringCellValue();
data.add(String);
}
}
this.data = data;
}
Redisplay data by standard JSF means: bind the retrieved list to some iterative component, ajax-update it, etc.
This question already has answers here:
How to provide a file download from a JSF backing bean?
(5 answers)
Closed 5 years ago.
I want to download a .txt/.log file saved in hard disk in JSF, am not getting any error but the issue is am not able to download the file, need some help..
note : am trying to zip the file first and then download.
I have tried :
response.setContentType("text/html");
response.setContentType("text/plain");
Code in page.xhtml:
<h:form>
<a4j:outputPanel id="downloadPanel">
<table><tr>
<td>
<h:commandButton id="dldFiles" title="Download File" image="/images/download.png"
style="width:20px; height:20px;"/>
</td>
<td>
<h:outputText value="Download log file" style="font-size: 11px; color:#56ADF8; font-weight: bold; cursor:pointer;"/>
</td>
</tr></table>
<a4j:support event="onclick" action="#{sqlLoaderAction.downloadFile}" reRender="uploadForm"></a4j:support>
</a4j:outputPanel>
</rich:panel>
</h:form>
In Actin Bean Methods:
public String downloadFile(){
System.out.println("--inside exportGoogleFeed--");
FacesContext fc = FacesContext.getCurrentInstance();
try{
User user = getUserBean();
Object sp = getServiceProxy(user);
HttpServletResponse response = ((HttpServletResponse)fc.getExternalContext().getResponse());
fc.responseComplete();
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition","attachment;filename=downloadname.zip");
OutputStream respOs = response.getOutputStream();
String dldFileName = "SQLLDR_28.txt";
PrintWriter pw1 = new PrintWriter(new FileWriter(dldFileName , false));
BufferedReader readbuffer = new BufferedReader(new FileReader("D:/Sqlldr_Container/downloadFile.txt"));
String strRead;
while((strRead=readbuffer.readLine())!=null){
pw1.println(strRead);
}
pw1.close();
File fil = new File(dldFileName);
ZipUploadStatusFile(dldFileName, respOs);
boolean bool = fil.delete();
System.out.println("-------Temp file Created deleted - "+bool+" ------------");
readbuffer.close();
}
catch (UnAuthenticatedException e) {
e.printStackTrace();
} /*catch (UnAuthorizedAccessException e) {
e.printStackTrace();
}*/ catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void ZipUploadStatusFile(String fileName, OutputStream respOs){
try{
ZipOutputStream out = new ZipOutputStream(respOs);
byte[] data = new byte[1000];
BufferedInputStream in = new BufferedInputStream
(new FileInputStream(fileName));
int count;
out.putNextEntry(new ZipEntry(fileName));
while((count = in.read(data,0,1000)) != -1){
out.write(data, 0, count);
}
in.close();
out.flush();
out.close();
System.out.println("Your file is zipped");
}catch(Exception e){
e.printStackTrace();
}
}
After executing the above method am getting below screen:
Thank you.....
You can't download files by ajax. JavaScript has due to security reasons no facilities to force a Save As dialogue. The best it could do in your particular case is to display the response inline.
Get rid of the <a4j:support> and make it a fullworthy synchronous request by putting the action method straight in the <h:commandButton>.
This is the code that will fulfill the needs of downloading text file in to client system.
public String downloadFileText() {
File file = new File(GlobalPath);
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setHeader("Content-Disposition", "attachment;filename=file.txt");
response.setContentLength((int) file.length());
ServletOutputStream out = null;
try {
FileInputStream input = new FileInputStream(file);
byte[] buffer = new byte[1024];
out = response.getOutputStream();
int i = 0;
while ((i = input.read(buffer)) != -1) {
out.write(buffer);
out.flush();
}
FacesContext.getCurrentInstance().getResponseComplete();
} catch (IOException err) {
err.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException err) {
err.printStackTrace();
}
}
return null;
}
I dont think that the code will run fine because the code is in JSF MAnaged beans and it is running at server side, so file will be downloaded at the system where application server is running, now what you need to do is to check , use two pcs,
In one pc deploy the web and try to download file from other pc, then check the behaviour of code, if the file could be downloaded in client pc then thats fine other wise you need to find alternatives
I'm very new to PrimeFaces components. I have a FileUpload (multiple files uploaded) and I want to know if there's a way to know how many files are in the upload component before uploading them.
What I need is to upload 1 to 6 files and just after the 6th is uploaded process the all the files.
Any idea on how can I achieve this is very welcome.
Cheers
UPDATE
Already tried with oncomplete but it does not help me 'cause this event is executed every time a file is uploaded not 'till all files are.
Ok, this is pretty old thread but I've found straitforward way to determine the number of files been uploaded.
p:fileUpload widget has an array with meta-info about selected files. By passing the length of this array to your bean you will obtain the total number of files.
There is a problem though: p:fileUpload doesn't submit the surrounding form, so I had to put invisible button along with the h:inputHidden to pass the number of files from JavaScript to ManagedBean:
<h:form id="importDlgForm">
<p:fileUpload id="importFile" widgetVar="importFile" fileUploadListener="#{importDialogView.importFile}"
mode="advanced" multiple="true"
onstart="$('#importDlgForm\\:file_number_input').val(PF('importFile').files.length);
$('#importDlgForm\\:submit_btn').click();"/>
<h:inputHidden id="file_number_input" value="#{importDialogView.importFileNumber}"/>
<p:commandButton id="submit_btn" style="display: none"/>
</h:form>
I also had to use AtomicInteger in order to track processed files, as p:fileUpload uses multiple threads to upload files by default.
private final AtomicInteger atomicImportFileNumber = new AtomicInteger();
private Integer importFileNumber;
public Integer getImportFileNumber() {
return importFileNumber;
}
public void setImportFileNumber(Integer importFileNumber) {
this.importFileNumber = importFileNumber;
atomicImportFileNumber.set(importFileNumber);
}
public void importFile(FileUploadEvent event) {
// common file upload stuff
if (atomicImportFileNumber.decrementAndGet() == 0) {
// part to execute only when all files have been uploaded
}
}
If you want to upload all the files, all 6 of them at once or only 1 at a time, and then call a processing message, you have to create a variable or better a list where you insert the name of each file, or even the file objects and when the ArrayList size reach 6 you call a processing method. Simple as that!
private ArrayList<UploadedFile> listWithUploadedFile = new ArrayList<UploadedFile>();
public void uploadMethod(){
//upload file, save input stream and any other thing you want
listWithUploadedFile.add(file);
if(listWithUploadedFile.size==6){
myProcessUploadedFilesMethod();
}
}
I've modified the Aleksandr's answer to simplify the onstart command, by the price of more complicated Java part.
</div>
<p:fileUpload widgetVar="importFile" listener="#{fileUploadView.handleFileUpload}" dragDropSupport="true" mode="advanced" multiple="true"
onstart="rc([{name:'size', value:PF('importFile').files.length}])"/>
<p:remoteCommand name="rc" update="messages" actionListener="#{fileUploadView.setSize}" />
</div>
and
#Named
#ViewScoped
public class FileUploadView {
private AtomicInteger size = new AtomicInteger();
private List<UploadedFile> files = new ArrayList<>();
public void setSize(ActionEvent e) {
String length = e.getFacesContext().getExternalContext().getRequestParameterMap().get("size");
if(length != null) {
size.set(Integer.parseInt(length));
}
}
public void handleFileUpload(FileUploadEvent event) {
files.add(event.getFile());
if(size.decrementAndGet() == 0) {
FacesMessage msg = new FacesMessage("Successful", files.size() + " uploaded");
FacesContext.getCurrentInstance().addMessage(null, msg);
files.clear();
}
}
}