when read excel how to skip some invalid characters - apache-poi

Read some excel using poi failed, encountered such an error
Caused by: org.xml.sax.SAXParseException; systemId: file://; lineNumber: 105; columnNumber: 147342; An invalid XML character (Unicode: 0xffff) was found in the element content of the document.
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
From xl/sharedStrings.xml, there exist <ffff> cause this problem.
How could read it successfully and just ignore these invalid characters? e.g.
aaa <ffff> bbb ==> aaa bbb

Those invalid characters should not be in the XML and Excel itself will not put them into there. So someone probably had done something wrong while creating that file using something else than Excel. That error should be avoided rather than trying to ignore the symptoms.
But I know how it feels to be depemdent on others work which will be done in far future, if even. So one needs improvising. But that is in this case only possible using ugly low level methods. Because the XML is invalid, parsing XML is not possible. So only String replacing will be possible.
In APACHE POI EXCEL XmlException: is an invalid XML character, is there any way to preprocess the excel file? I had schown this already. In that case to replace UTF-16-surrogate-pair numeric character references which also are invalid in XML.
In following I will show a code which is more flexible to add multiple other repairing actions to /xl/sharedStrings.xml if necessary.
The principle is using OPCPackage, which is the *.xlsx ZIP package, to get out the /xl/sharedStrings.xml as text string. Then do the needed replacings and put the repaired /xl/sharedStrings.xml back into the OPCPackage. Then do creating the XSSFWorkbook from that repaired OPCPackage instead of from the corrupt file.
import java.io.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.openxml4j.opc.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class RepairSharedStringsTable {
static String removeInvalidXmlCharacters(String string) {
String xml10pattern = "[^"
+ "\u0009\r\n"
+ "\u0020-\uD7FF"
+ "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff"
+ "]";
string = string.replaceAll(xml10pattern, "");
return string;
}
static void repairSharedStringsTable(OPCPackage opcPackage) {
for (PackagePart packagePart : opcPackage.getPartsByName(Pattern.compile("/xl/sharedStrings.xml"))) {
String sharedStrings = "";
try (BufferedInputStream inputStream = new BufferedInputStream(packagePart.getInputStream());
ByteArrayOutputStream sharedStringsBytes = new ByteArrayOutputStream() ) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
sharedStringsBytes.write(buffer, 0, length);
}
sharedStrings = sharedStringsBytes.toString("UTF-8");
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(sharedStrings);
//sharedStrings = replaceUTF16SurrogatePairs(sharedStrings);
sharedStrings = removeInvalidXmlCharacters(sharedStrings);
//sharedStrings = doSomethingElse(sharedStrings);
System.out.println(sharedStrings);
try (BufferedOutputStream outputStream = new BufferedOutputStream(packagePart.getOutputStream()) ) {
outputStream.write(sharedStrings.getBytes("UTF-8"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("./Excel.xlsx"))) {
System.out.println("success");
} catch (Exception ex) {
System.out.println("failed");
ex.printStackTrace();
}
OPCPackage opcPackage = OPCPackage.open(new FileInputStream("./Excel.xlsx"));
repairSharedStringsTable(opcPackage);
opcPackage.flush();
try (XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
FileOutputStream out = new FileOutputStream("./ExcelRepaired.xlsx");) {
workbook.write(out);
System.out.println("success");
} catch (Exception ex) {
System.out.println("failed");
ex.printStackTrace();
}
}
}

In my case below files all have invalid characters
xl/sharedStrings.xml
xl/worksheets/sheet1.xml
xl/worksheets/sheet8.xml
All these xml should be processed
opcPackage.getPartsByName(Pattern.compile("(/xl/sharedStrings.xml)|(/xl/worksheets/.+\\.xml)"))

Related

SXSSFWorkbook "File contains corrupted data" Error using OpenXml after upgrading from 3.17 to 5.2 or 5.2.2

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()));
}
}

How fix System.FormatException reading data from text file to a listbox

My code takes data from form application and displays the result in a listbox and save the data in a file. When next I load the code it should read the data from the file and populate the listbox. I am have a System.FormatException Input string not in correct format.
The code works until I am ready to read the file. I have removed the whitespaces and the dollar sign but the problem is still there. Please any help will be appreciated.
My FileIO class code below
public static class FileIO
{
const string path = "Customers.txt";
// writes data from the array to the file
public static void WriteData(List<Customer> customers)
{
FileStream fs = null;
StreamWriter sw = null;
try
{
// open the file for writing; overwrite old content
fs = new FileStream(path, FileMode.Create, FileAccess.Write);
sw = new StreamWriter(fs);
// write data
foreach (Customer item in customers)
sw.WriteLine(item.DisplayCustomersInfo("|"));
}
catch (Exception ex)
{
MessageBox.Show("Error while writing to the file: " +
ex.Message, ex.GetType().ToString());
}
finally
{
if (sw != null) sw.Close(); // also closes fs
}
}
// reads data from the file, puts in a list, and returns it
public static List<Customer> ReadData()
{
List<Customer> customers = new List<Customer>();
FileStream fs = null;
StreamReader sr = null;
string line; // for reading
string[] columns; // result from splitting the line
// open the file for reading and read number into data
try
{
fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
sr = new StreamReader(fs);
while (!sr.EndOfStream) // while there is data in the file
{
line = sr.ReadLine(); // read the next line
line.Trim();
columns = line.Split(','); // split line into substring from line with comma delimiters
Customer c = new Customer(Convert.ToInt32(columns[0]), columns[1], Convert.ToChar(columns[2]),
Convert.ToDecimal(columns[3].Remove(0, 1)));//this is where I think the problem is.
customers.Add(c);
}
}
catch (FormatException)
{
MessageBox.Show("File contains bad format data. Aborting reading");
}
catch (Exception ex)
{
MessageBox.Show("Error while reading the file: "
+ ex.Message, ex.GetType().ToString());
}
finally
{
// close the file if open
if (sr != null) sr.Close(); //file stream gets closed too
}
return customers;
}
}
Below is the text file.
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
I have used , and ; as delimiters prior to using |.
I expect to read data from the file and populate the listbox and add more data.

cannot access the file because it is using by another program Error

I have been fighting with this issue since last week.still not able to solve.
i am sending file to client machine once i get in server automatically.but so many time when i handle file it throw an error that Cannot access the file because it is using by another program.
below my code
private static string SaveFileStream(string filePath, Stream stream, string Filename1)
{
string localresponse;
try
{
//this.SaveFileStream(System.Configuration.ConfigurationSettings.AppSettings[fileToPush.FileType].ToString() + "\\" + fileToPush.FileName, new MemoryStream(fileToPush.Content));
if (File.Exists(filePath))
{
File.Delete(filePath);
}
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fileStream);
fileStream.Flush();
fileStream.Dispose();
}
FileInfo info = new FileInfo(filePath);
ExtractFile(info);
localresponse = "Successful";
}
catch (Exception ex)
{
localresponse = ex.Message;
}
return localresponse;
}

Convert office document to pdf and display it on the browser

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!!

J2ME XML Parsing

I have another question about a "JDWP Error: 21" logged: Unexpected JDWP Error 21
I am trying to parse some XML I gather from a servlet into a J2ME MIDlet with the code below. So far unsuccessfully, I think due to the JDWP error on my HttpConnection how ever the InputStream is filled with XML and once parsed everything inside the Document is null.
Has anyone got and ideas about the JDWP error, and also does that code look like it should work?
In MIDlet I am using JSR-172 API javax.xml.parsers.*.
if(d==form1 && c==okCommand)
{
// Display Webpage
webPage = new TextBox(txtField.getString(),
"",
100000,
TextField.ANY
);
Display.getDisplay(this).setCurrent(webPage);
try
{
HttpConnection conn = (HttpConnection)Connector.open("http://localhost:8080/Blogging_Home/Interface?Page=Bloggers&Action=VIEW&Type=XML");
conn.setRequestMethod(HttpConnection.GET);
int rc = conn.getResponseCode();
getConnectionInformation(conn, webPage);
webPage.setString(webPage.getString() + "Starting....");
String methodString = getStringFromURL("");
if (rc == HttpConnection.HTTP_OK)
{
InputStream is = null;
is = createInputStream(methodString);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document document;
try
{
builder = factory.newDocumentBuilder();
document = builder.parse(is);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
webPage.setString(webPage.getString() + "ERROR:" + rc);
}
}
catch(Exception ex)
{
// Handle here
webPage.setString("Error" + ex.toString());
}

Resources