At first I thought the workbook is not disposed as in here :
xlsx file content is corrupted...
but this wasn’t the case. I was closing it explicitly by workbook .close(), I even had a workbook.dispose() I then switched to try-with-resource,none helped.
Microsoft excel is opening either file (from 3.17 or 5.2) without an issue but 5.2 \ 5.2.2 files are crushing when opening them in OpenXml .
opening the .xlsx file:
public Test(string fileName)
{
//Stream = new StreamReader(fileName);
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false)) // this will throw exception
{
}
}
Exception:
Important things:
I noticed that if I unpack the excel file in the new version (using 7zip) and repack it again, it makes the file load up without issues in OpenXml! but without doing it manually (which I cannot as the process should be automated) the issue persists. this directs me to an issue of compression rather than writing & closing \ writing violations of the SXSSFWorkbook object into a file (especially because all rows and columns look the same in both 3.17 \ 5.2 versions, using MS excel). the latest POI lib is using the latest commons-compress version 1.21, but I saw no known issue there according to my search.
I also made the file very small with a few rows just to make sure it's not a size issue , checking this link, and setting didn't work as well Writing very large file via SXSSF leads to corrupt file
Maybe there is another way to compress the excel file which I'm not aware of or properties that I should change for the SXSSDWorkbook in order to resolve this issue?
When I switch the code to work with XSSFWorkbook instead of SXSSFWorkbook I have no issues in 5.2 ! The problem is I need to keep the current performance intact.
I also tried returning the workbook object at each method call to keep its reference and then close the object (the code doesn’t show that entirely now, as I switched to try-with-resource and I expect it to work.)
The object doesn’t seem closed even after close is called (debugging the internal poi lib), as the GC may have not worked yet. but even if I kill the debugger and stop the app and open the files long after the creation. They are still corrupted.
I tried looking for places where I might do something wrong with the SXSSFWorkbook but I spotted nothing special, I didn’t see any overriding of cell \ row data as suggested in some forums, since SXSSF is a stream read-only object.
I used 7zip to open the corrupted file vs the uncorrupted file from version 3.17, and noticed there is a missing Modified date in the corrupted one and some size differences.
Also the new version is readable while the old and working poi 3.17 version sheet.xml is unreadable (could be encrypted ? ) for example, I have 2 sheets,I opened the smaller one
The commons-compress version POI is using is the latest (1.21) , I deleted it and re-ran maven to see that it gets back to m2 folders
So, it’s either a bug , or a new enforcement of SXSSFWorkbook of certain unwelcomed things I do with the object, which I cannot spot in my code.
Here is the entire code that uses SXSSFWorkbook, and inner methods that are relevant :
public void generateReport(Report report,
HashMap<String, LocalizationBundle> localizationMapping,
boolean isLocalizationEnabled,
CategoriesBundle categoriesBundle,
String generateStartTime,
int backgroundNumOfRows,
String reportZipPassword) throws Exception {
String reportGuid = report.getReportGUID();
String userId = report.getUserId();
String reportName = report.getName();
String outputFileName = "";
String reportParameters = String.format("-> Report guid: %s report name: %s user id: %s . ", reportGuid, reportName, userId);
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("In dal.generateReport() -> Started creating report. reportParameters: %s", reportParameters));
SheetInfo sheetInfoObject = null;
try {
// The Current row number int eh current sheet
final String categoryHitSign = "1";
final String categoryNotHitSign = "";
String csvFolder;
// Create temporary folder for the report.
// build since for sometimes the first report deleted all files of the other threads
File poiTempFileDirectory = new File(System.getProperty("java.io.tmpdir"), reportGuid);
TempFileCreationStrategy newTempFileCreationStrategy = createTempFileCreationStrategy(poiTempFileDirectory);
TempFile.setTempFileCreationStrategy(newTempFileCreationStrategy);
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("poiTempFileDirectory: %s. reportParameters: %s", poiTempFileDirectory, reportParameters));
//The POI objects
try (SXSSFWorkbook workBook = new SXSSFWorkbook(ReportsConstants.NUM_OF_ROWS_TO_FLUSH)) {
workBook.setCompressTempFiles(true);
// workBook.setZip64Mode(Zip64Mode.Always);
setCellStyles(workBook);
// Create the CsvParser
CsvParserSettings settings = new CsvParserSettings();
settings.setMaxCharsPerColumn(csvMaxCharPerColumn);
settings.setLineSeparatorDetectionEnabled(true);
CsvParser csvParser = new CsvParser(settings);
// Get the localization bundle
LocalizationBundle localizationBundle = this.getLocalizationBundle(localizationMapping, report.getLanguageCode(), report.getCountryCode());
// Get the folder of the CSV files
csvFolder = getReportTempFolder(report);
//The CSV input file list (sorted). These later will be deleted
File[] csvFilesList = this.getSortedCSVFiles(csvFolder);
if (csvFilesList == null) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - CSV folder %s is empty. reportParameters: %s", csvFolder, reportParameters));
// no way to continue if the the files array is null.
return;
}
StringBuilder csvFilesBuilder = new StringBuilder();
Arrays.stream(csvFilesList).forEach(file -> csvFilesBuilder.append(file.getPath()).append(" \n"));
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("csvFiles: %s , reportParameters: %s", csvFilesBuilder.toString(), reportParameters));
// Open the output file (xlsx\zip file)
outputFileName = this.getReadyReportFilePath(report);
try (FileOutputStream outputStream = createFileStream(outputFileName, reportParameters)) {
this.createSummarySheet(workBook, report, localizationBundle, isLocalizationEnabled, generateStartTime);
HashSet<String> categoriesFoundInReport = new HashSet<>();
boolean categoriesSplitFlagOn = this.getSplitCategoriesFlag(report);
if (categoriesSplitFlagOn) {
categoriesFoundInReport = findCategoriesInReport(true, csvParser, csvFilesList, categoriesBundle);
}
csvParser = new CsvParser(settings);
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("Beginning csvParser work on files, Displaying sorted csv files list paths and row values in TRACE mode only. reportParameters: %s",
reportParameters));
// A single line from the CSV file
sheetInfoObject = parseCsvFiles(report,
csvFilesList,
csvParser,
reportParameters,
categoriesBundle,
categoriesFoundInReport,
categoryHitSign,
categoryNotHitSign,
workBook,
localizationBundle,
isLocalizationEnabled,
categoriesSplitFlagOn);
// Add the num of rows of the last sheet (the bulk that was not added in the modulo condition: if (sheetInfo.getSheetRowNum() % this.numRowsInSheet == 0) - without the columns header row.
sheetInfoObject.setTotalNumOfRows(sheetInfoObject.getTotalNumOfRows() + sheetInfoObject.getSheetRowNum());
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("ReportsFileManager - generateReport. updating summary sheet with total num of rows. reportParameters: %s", reportParameters));
this.updateSummaryTotalRows(workBook, sheetInfoObject.getTotalNumOfRows(), backgroundNumOfRows, localizationBundle);
// Write the Stream and close it
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("ReportsFileManager - generateReport. write the output stream. reportParameters: %s", reportParameters));
workBook.write(outputStream);
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("ReportsFileManager - generateReport. closed the output stream. reportParameters: %s", reportParameters));
// On enriched mode
if (report.getReportTemplateObject().getTemplateType().equalsIgnoreCase(Configuration.EnrichedLicense)) {
AppLogger.debug(LoggerCategories.DataAccessLayer, "In Enriched Mode, Zipping output.");
// Zip the csv output and password protect it.
this.zipAndProtectCsvOutput(outputFileName, reportZipPassword);
}
}
//workBook.dispose(); //Tried with \ without , still corrupted.
}
} catch (FileNotFoundException e) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("An exception occurred in ReportsFileManager - generateReport. FileNotFoundException. Error: %s, Cause: %s reportParameters: %s, %s stack trace: %s",
e.getMessage(),
e.getCause(),
reportParameters,
Arrays.toString(Thread.currentThread().getStackTrace()).replace(",", "%n")));
throw e;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
} finally {
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("Finished creating report reportParameters: %s", reportParameters));
try {
if (report.getReportTemplateObject().getTemplateType().equalsIgnoreCase(Configuration.EnrichedLicense) && !StringUtils.isEmptyOrWhiteSpace(outputFileName)) {
this.deleteReadyReportFileByPath(outputFileName);
}
deletePoiTemporaryFolder(reportGuid);
this.deleteCSVFolder(report);
} catch (Exception finalException) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("An exception occurred in ReportsFileManager- generateReport's Finally . General Exception Error: %s, Cause: %s, reportParameters: %s, stack trace: %s",
finalException.getMessage(),
finalException.getCause(),
reportParameters,
Arrays.toString(Thread.currentThread().getStackTrace()).replace(",", "%n")));
}
}
}
private SXSSFWorkbook setCellStyles(SXSSFWorkbook workBook) {
Font summaryTitleFont = workBook.createFont();
summaryTitleFont.setColor(IndexedColors.WHITE.getIndex());
summaryTitleFont.setBold(true); summaryTitleFont.setFontHeightInPoints(ReportsConstants.SUMMARY_REPORT_TITLE_FONT_SIZE);
summaryTitleStyle = workBook.createCellStyle();
summaryTitleStyle.setAlignment(HorizontalAlignment.CENTER);
summaryTitleStyle.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex());
summaryTitleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
summaryTitleStyle.setFont(summaryTitleFont);
Font columnsHeadersFont = workBook.createFont();
columnsHeadersFont.setColor(IndexedColors.WHITE.getIndex());
columnsHeadersFont.setBold(true);
columnsHeadersFont.setFontHeightInPoints(ReportsConstants.REPORT_HEADERS_FONT_SIZE);
columnsHeadersStyle = workBook.createCellStyle();
columnsHeadersStyle.setAlignment(HorizontalAlignment.CENTER);
columnsHeadersStyle.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex());
columnsHeadersStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
columnsHeadersStyle.setFont(columnsHeadersFont);
Font summaryFieldsFont = workBook.createFont();
summaryFieldsFont.setBold(true);
summaryFieldsStyle = workBook.createCellStyle();
summaryFieldsStyle.setFont(summaryFieldsFont);
return workBook;
}
private FileOutputStream createFileStream(String outputFileName, String reportParameters) throws Exception {
FileOutputStream outputStream = null;
try {
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("Got output file name: %s for report - report parameters: %s , creating file output stream...", outputFileName, reportParameters));
outputStream = new FileOutputStream(outputFileName, false);
} catch (Exception outputStreamEx) {
try {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("An exception occurred in ReportsFileManager while creating FileOutputStream "
+ "could not create a file with the path %s. attempting to create the entire path and file"
+ "Error: %s, Cause: %s, report parameters: %s stack trace: %s",
outputFileName,
outputStreamEx.getMessage(),
outputStreamEx.getCause()),
reportParameters,
Arrays.toString(Thread.currentThread().getStackTrace()).replace(",", "%n"));
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - creating new file %s report parameters: %s",
outputFileName, reportParameters));
File f = new File(outputFileName);
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - done creating new file %s report parameters: %s",
outputFileName, reportParameters));
if (f.getParentFile() != null && !f.getParentFile().exists()) {
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - the parent file %s for outputFileName: %s, did not exist for report, making directories. report parameters: %s",
f.getParentFile().getPath(), outputFileName, reportParameters));
if (f.getParentFile().mkdirs()) {
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - the parent directories of %s were created "
+ "report parameters: %s ", f.getParentFile().getPath(), reportParameters));
} else {
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - could not create parent directories for %s"
+ "report parameters: %s ", f.getParentFile().getPath(), reportParameters));
}
if (!f.exists()) {
f.createNewFile();
}
} else {
throw new Exception("Could not get parent file.");
}
outputStream = new FileOutputStream(outputFileName, false);
} catch (Exception ex) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("An exception occurred in ReportsFileManager while second attempt of creating FileOutputStream in path %s"
+ " please contact system admin / support. Error: %s, Cause: %s report parameters: %s, stack trace: %s",
outputFileName,
ex.getMessage(),
ex.getCause()),
reportParameters,
Arrays.toString(Thread.currentThread().getStackTrace()).replace(",", "%n"));
throw ex;
}
}
return outputStream;
}
private SXSSFWorkbook createSummarySheet(SXSSFWorkbook workBook, Report report, LocalizationBundle localizationBundle, boolean isLocalizationEnabled, String generateStartTime) {
int rowNum = 0;
String tenantAndChannel = String.format("%s_%s", report.getTenantId(), report.getChannel());
String sheetName = String.format("%s %s", report.getName(), getLocalizationTransfer(localizationBundle, isLocalizationEnabled, ReportsConstants.SUMMARY_SHEET_SUFFIX_KEY, tenantAndChannel));
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("Before creating new sheet on report guid %s , report name: %s , sheet name %s", report.getReportGUID(), report.getName(), sheetName));
SXSSFSheet currentSheet = workBook.createSheet(sheetName);
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("After creating new sheet on report guid %s , report name: %s , sheet name %s", report.getReportGUID(), report.getName(), sheetName));
this.insertSummaryTitle(currentSheet.createRow(rowNum++), getLocalizationTransfer(localizationBundle, isLocalizationEnabled, ReportsConstants.SUMMARY_REPORT_TITLE_KEY, tenantAndChannel));
this.insertSummaryField(currentSheet.createRow(rowNum++), getLocalizationTransfer(localizationBundle, isLocalizationEnabled, ReportsConstants.SUMMARY_PROJECT_FIELD_KEY, tenantAndChannel), report.getChannelDisplayName());
this.insertSummaryField(currentSheet.createRow(rowNum++), getLocalizationTransfer(localizationBundle, isLocalizationEnabled, ReportsConstants.SUMMARY_CREATED_FIELD_KEY, tenantAndChannel), getFormatedDate(generateStartTime));
this.insertSummaryField(currentSheet.createRow(rowNum++), getLocalizationTransfer(localizationBundle, isLocalizationEnabled, ReportsConstants.SUMMARY_BY_FIELD_KEY, tenantAndChannel), report.getReportCreator());
this.insertSummaryField(currentSheet.createRow(rowNum++), getLocalizationTransfer(localizationBundle, isLocalizationEnabled, ReportsConstants.SUMMARY_NUM_OF_RESULT_FIELD_KEY, tenantAndChannel), "");
this.numOfResultsRowIndex = rowNum - 1;
if (!StringUtils.isEmptyOrWhiteSpace(report.getQueryTitle())) {
rowNum++;
this.insertSummaryField(currentSheet.createRow(rowNum++), report.getQueryTitle(), null);
this.insertHashMap(currentSheet, report.getQueryMap());
rowNum = currentSheet.getLastRowNum() + 1;
}
if (report.getBackgroundMap().size() > 0) {
rowNum++;
this.insertSummaryField(currentSheet.createRow(rowNum++), report.getBackgroundTitle(), null);
this.insertHashMap(currentSheet, report.getBackgroundMap());
}
currentSheet.setColumnWidth(0, ReportsConstants.SUMMARY_COLUMNS_WIDTH);
currentSheet.setColumnWidth(1, ReportsConstants.SUMMARY_COLUMNS_WIDTH);
return workBook;
}
private SheetInfo parseCsvFiles(Report report, File[] csvFilesList, CsvParser csvParser,
String reportParameters, CategoriesBundle categoriesBundle,
HashSet<String> categoriesFoundInReport, String categoryHitSign,
String categoryNotHitSign, SXSSFWorkbook workBook, LocalizationBundle localizationBundle,
boolean isLocalizationEnabled, boolean categoriesSplitFlagOn) {
int categoriesColumnsIndex = -1;
int textTotalColumnsIndex = -1;
boolean isFirstCsvFile = true;
String[] line;
//the Header string to be kept for each sheet and the categories columnsIndex
String[] headerLine = null;
// The Current sheet index (the row number can't be more then "numOfRowsInSheet", the XSL max row limitation)
SheetInfo sheetInfoObject = new SheetInfo();
for (File file : csvFilesList) {
try {
AppLogger.trace(LoggerCategories.DataAccessLayer, String.format("Sorted csv files list path: %s reportParameters: %s - parsing the csv file now..", file.getPath(), reportParameters));
csvParser.beginParsing(file);
// Start reading the file (only if there are lines to read)
while ((line = csvParser.parseNext()) != null) {
// If we are in the first csv file - we need to take the columns headers
if (isFirstCsvFile == true) {
headerLine = line;
// Get the categories column index
categoriesColumnsIndex = Arrays.asList(headerLine).indexOf(ReportsConstants.CATEGORIES_COLUMN_KEY);
isFirstCsvFile = false;
//check if the report has text_<language>_total
String textTotalFL = findTextInRequest(String.join(",", line));
textTotalColumnsIndex = Arrays.asList(headerLine).indexOf(textTotalFL);
// Go to the next line
continue;
}
//if text total column exists and we are not running on headers row (first line)
if (textTotalColumnsIndex != -1 && !isFirstCsvFile) {
try {
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("ReportsFileManager.generateReport() - line.length is %s. reportParameters: %s", line.length, reportParameters));
//Replace escaped commas with regular commas ("\," -> ",") on last row
if (line[line.length - 1] != null) {
line[line.length - 1] = line[line.length - 1].replace("\\,", ",");
} else {
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("ReportsFileManager.generateReport() - the line[line.length - 1] is null. interactionId is :%s. reportParameters: %s ", line[0], reportParameters));
}
} catch (Exception ex) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("An exception occurred in ReportsFileManager - replace commas. Row number is : %s .Error: %s, Cause: %s report parameters: %s",
sheetInfoObject.getSheetRowNum(),
ex.getMessage(),
ex.getCause()),
reportParameters);
ex.printStackTrace();
throw ex;
}
}
sheetInfoObject = createRowInCurrentOrNewSheet(workBook,
headerLine,
categoriesFoundInReport,
categoryHitSign,
categoryNotHitSign,
reportParameters,
report,
localizationBundle,
categoriesBundle,
categoriesColumnsIndex,
line,
sheetInfoObject,
isLocalizationEnabled,
categoriesSplitFlagOn,
getNumRowsInSheet(report));
}
} catch (Exception ex) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("An exception occurred in ReportsFileManager - parse csv file operation . Error: %s, Cause: %s reportParameters: %s",
ex.getMessage(),
ex.getCause()),
reportParameters);
ex.printStackTrace();
throw ex;
}
}
return sheetInfoObject;
}
private SXSSFWorkbook updateSummaryTotalRows(SXSSFWorkbook workBook, int totalNumOfRows, int backgroundNumOfRows, LocalizationBundle localizationBundle) {
Row row;
Cell cell;
String cellValue;
int cellIndex = 1;
try {
SXSSFSheet summarySheet = workBook.getSheetAt(0);
row = summarySheet.getRow(this.numOfResultsRowIndex);
cell = row.getCell(cellIndex);
float percentage = ((float) (totalNumOfRows * ReportsConstants.MAGIC_NUMBER_100) / backgroundNumOfRows);
cellValue = String.format("%s %s %s (%.1f%%)", totalNumOfRows, localizationBundle.getTranslatedValue(ReportsConstants.SUMMARY_OUT_OF_KEY, ""), backgroundNumOfRows, percentage);
row.createCell(++cellIndex).setCellValue(totalNumOfRows);
row.createCell(++cellIndex).setCellValue(backgroundNumOfRows);
cell.setCellValue(cellValue);
} catch (Exception e) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("An exception occurred in ReportsFileManager - updateSummaryTotalRows. errorMessage: %s", e.getMessage()));
}
return workBook;
}
private void deletePoiTemporaryFolder(String reportGuid) {
int count = 0;
File poiTempFileDirectory = new File(System.getProperty("java.io.tmpdir"), reportGuid);
AppLogger.info(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - deletePoiTemporaryFolder - Delete POI temporary folder: %s ", poiTempFileDirectory.toString()));
try {
long startDeleteDirectory = System.currentTimeMillis();
if (poiTempFileDirectory.exists()) {
// Rerun again while their are files in the folder (because the "dispose" doesn't always delete the files on time)
while (poiTempFileDirectory.list().length > 0 && count < deleteTemporaryRetries) {
count++;
Thread.sleep(processingSleep);
}
FileUtils.deleteDirectory(poiTempFileDirectory);
long endDeleteDirectory = System.currentTimeMillis();
AppLogger.debug(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - deletePoiTemporaryFolder - delete temporary POI folder after: %d milliseconds", endDeleteDirectory - startDeleteDirectory));
}
} catch (InterruptedException ex) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - deletePoiTemporaryFolder - sleep InterruptedException: %s", ex.getMessage()));
} catch (IOException ex) {
AppLogger.error(LoggerCategories.DataAccessLayer, String.format("ReportFileManager - deletePoiTemporaryFolder - unable to Delete POI temporary folder: %s ,ErrorMessage: %s", poiTempFileDirectory.toString(), ex.getMessage()));
}
}
Please see the update question below (not the top one).
I tried to open any document type (especially PDF) on Liferay using this function. But I always get message Awt Desktop is not supported! as stated on the function. How can I enable the Awt Desktop? I tried searching over the internet and found nothing. Anyone help, pls? Thanks.
public void viewFileByAwt(String file) {
try {
File File = new File(getPath(file));
if (File.exists()) {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().open(File);
} else {
System.out.println("Awt Desktop is not supported!");
}
} else {
//File is not exists
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
Source: http://www.mkyong.com/java/how-to-open-a-pdf-file-in-java/
UPDATE
As you see the code below, both mode (1 for download and 2 for preview) is working pretty well, but unfortunately the second mode (preview mode) is works only for PDF.
Now what I want to do is, while user clicking the preview button, files another than PDF (limited only for extension: DOC, DOCX, XLS, XLSX, ODT, ODS) must be converted to PDF first, and then display it on the browser with the same way as below code explained. Is it possible to do that? If it's too hard to have all of the converter on a function, then on a separated function each extension would be fine.
public StreamedContent getFileSelected(final StreamedContent doc, int mode) throws Exception {
//Mode: 1-download, 2-preview
try {
File localfile = new File(getPath(doc.getName()));
FileInputStream fis = new FileInputStream(localfile);
if (mode == 2 && !(doc.getName().substring(doc.getName().lastIndexOf(".") + 1)).matches("pdf")) {
localfile = DocumentConversionUtil.convert(doc.getName(), fis, doc.getName().substring(doc.getName().lastIndexOf(".") + 1), "pdf");
fis = new FileInputStream(localfile.getPath());
}
if (localfile.exists()) {
try {
PortletResponse portletResponse = (PortletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpServletResponse res = PortalUtil.getHttpServletResponse(portletResponse);
if (mode == 1) res.setHeader("Content-Disposition", "attachment; filename=\"" + doc.getName() + "\"");
else if (mode == 2) res.setHeader("Content-Disposition", "inline; filename=\"" + doc.getName() + "\"");
res.setHeader("Content-Transfer-Encoding", "binary");
res.setContentType(getMimeType(localfile.getName().substring(localfile.getName().lastIndexOf(".") + 1)));
res.flushBuffer();
OutputStream out = res.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
buffer = new byte[4096];
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
Liferay is a portal server; its user interface runs in a browser. AWT is the Java 1.0 basis for desktop UIs.
I don't think AWT is the way to display it.
Why can't you open the file and stream the bytes to the portlet using the application/pdf MIME type?
You have to first install openoffice on your machine
http://www.liferay.com/documentation/liferay-portal/6.1/user-guide/-/ai/openoffice
After configuring openoffice with liferay, you can use DocumentConversionUtil class from liferay to convert documents.
DocumentConversionUtil.convert(String id, InputStream is, String sourceExtension,String targetExtension)
Above code will return inputstream. After this conversion you can show pdf in your browser
Hope this helps you!!