Apache POI Java heap space with xlsm file - apache

I am trying to execute the following code to convert a xlsm file to csv :
//Workbook wbk = new HSSFWorkbook(new FileInputStream(new File("myFile.xls")));
Workbook wbk = new XSSFWorkbook(new FileInputStream(new File("myFile.xlsm")));
for (int i = 0; i < wbk.getNumberOfNames(); i++) {
if (wbk.getNameAt(i).getNameName().startsWith("START\\")) {
// Get SheetName
sheetName = wbk.getNameAt(i).getSheetName();
// Get csv Filename
csvFilename = generateFileName(wbk.getNameAt(i).getNameName(), currentDate);
// Starting row index for this sheet
startingRowIndex = getStartingRowIndex(wbk, i);
// Max column index for this sheet
maxColumnIndex = getMaxColumnIndex(wbk, wbk.getSheet(sheetName));
// Convert sheet to csv
toCSV(csvFilename, startingRowIndex, maxColumnIndex, wbk, sheetName);
}
}
-Xmx argument is setted to 1024 and i use a xslm file.
This file is 15 Mo.
I get this error "java.lang.OutOfMemoryError: Java heap space" on the first line.
With the same file in xls format (50 Mo), it works great.
I can't change the Xmx argument and I can't use other API than POI.
I read in others messages that the better way is to use the SAX API for this kind of memory problems.
However, in my file, all sheets and all rows don't need to be extracted in CSV.
That is why I use "wbk.getNumberOfNames()" to get all the defined names (in the name manager) and to know the sheets to convert.
Do you know how i can access these properties using SAX API ?
Thanks.
Regards.

The following Apache POI code example uses SAX parser to convert XLSX file to CSV.
http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java

Related

How do you modify this script to run TinyPNG on opened files instead of having to use the open dialog to select a file?

I'm trying to modify this script to compress and then close all the opened files with the TinyPNG Photoshop plugin as opposed to having to choose one file at a time in an open dialog box. They do offer another script that allows you to compress a whole folder. However, I find myself needing to compress 10 out 50 images in a folder so I'd rather just be able to select those 10 or to open those 10 and run the script on all open files.
I've tried replacing
compressFile(File.openDialog("Choose a PNG or JPEG file to compress")
with
compressFile(app.activeDocument)
in an attempt to have the script just compress the current document.
Instead of using the active document it simply skips to the catch(error).
try {
// Compress Active File
compressFile(File.openDialog("Choose a PNG or JPEG file to compress"));
} catch(error) {
alert("No JPEG or PNG file selected or compression error.");
}
compressFile() requires a File object while activeDocument is a document object.
For opened documents you'll want a loop through the documents:
for (var i = documents.length - 1; i >= 0; i--) {
activeDocument = documents[i];
compressFile()
}
and in compressFile() you should get rid opener part (because all the documents are already opened) but you'll need to replace a file with actual document path:
// Compress the document
var tinify = new ActionDescriptor();
tinify.putPath(charIDToTypeID("In "), new File(activeDocument.path + "/" + activeDocument.name)); /* Overwrite original! */
tinify.putUnitDouble(charIDToTypeID("Scl "), charIDToTypeID("#Prc"), percentage);
For a files dialogue you can simply modify the last bit of Compress File.jsx:
//dialogue to select multiple files:
var startFolder = Folder.myDocuments,
myFiles = startFolder.openDlg(void(0), void(0), true);
if (myFiles != null) //if the dialogue wasn't cancelled
{
//launch compressFile for every selected file
for (var i = myFiles.length - 1; i >= 0; i--)
{
compressFile(myFiles[i])
}
}

Read data from excel data by JSPDynpage

Please help me with the below issue.
I have to read data from excel .
I have created JSPDynpage component and followd below link :
http://help.sap.com/saphelp_sm40/helpdata/en/63/9c0e41a346ef6fe10000000a1550b0/frameset.htm below is my code. I am trying to read excel file using apache poi 3.2 API
try
{
FileUpload fu = (FileUpload)
this.getComponentByName("myfileupload");
// this is the temporary file
if (fu != null) {
// Output to the console to see size and UI.
System.out.println(fu.getSize());
System.out.println(fu.getUI());
// Get file parameters and write it to the console
IFileParam fileParam = fu.getFile();
System.out.println(fileParam);
// Get the temporary file name
File f = fileParam.getFile();
String fileName = fileParam.getFileName();
// Get the selected file name and write ti to the console
ivSelectedFileName = fu.getFile().getSelectedFileName();
File fp = new File(ivSelectedFileName);
myLoc.errorT("#fp#"+fp);
try {
//
**FileInputStream file = new FileInputStream(fp);** --> error at this line
HSSFWorkbook workbook = new HSSFWorkbook(file);
myLoc.errorT("#workbook#"+workbook);
//Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);
myLoc.errorT("#sheet#"+sheet);
//
} catch(Exception ioe) {
myLoc.errorT("#getLocalizedMessage# " + ioe.getLocalizedMessage());
}
Error :
#getLocalizedMessage# C:\Documents and Settings\10608871\Desktop\test.xls (The system cannot find the path specified)
at line FileInputStream file = new FileInputStream(fp);
I have created the PAR file and deploying it on server.
Thanks in Advance,
Aliya Khan.
i resolved the problem, i was passing the worng parameter instead of f
FileInputStream file = new FileInputStream(f);

Process a CSV file starting at a predetermined line/row using LumenWorks parser

I am using LumenWorks awesome CSV reader to process CSV files. Some files have over 1 million records.
What I want is to process the file in sections. E.g. I want to process 100,000 records first, validate the data and then send this records over an Internet connection. Once sent, I then reopen the file and continue from record 100,001. On and on till I finish processing the file. In my application I have already created the logic of keeping track of which record I am currently processing.
Does the LumenWorks parser support processing from a predetermined line in the CSV or it always has to start from the top? I see it has a buffer variable. Is there a way to use this buffer variable to achieve my goal?
my_csv = New CsvReader(New StreamReader(file_path), False, ",", buffer_variable)
It seems the LumenWorks CSV Reader needs to start at the top - I needed to ignore the first n lines in a file, and attempted to pass a StreamReader that was at the correct position/row, but got a Key already exists Dictionary error when I attempted to get the FieldCount (there were no duplicates).
However, I have found some success by first reading pre-trimmed file into StringBuilder and then into a StringReader to allow the CSV Reader to read it. Your mileage may vary with huge files, but it does help to trim a file:
using (StreamReader sr = new StreamReader(filePath))
{
string line = sr.ReadLine();
StringBuilder sbCsv = new StringBuilder();
int lineNumber = 0;
do
{
lineNumber++;
// Ignore the start rows of the CSV file until we reach the header
if (lineNumber >= Constants.HeaderStartingRow)
{
// Place into StringBuilder
sbCsv.AppendLine(line);
}
}
while ((line = sr.ReadLine()) != null);
// Use a StringReader to read the trimmed CSV file into a CSV Reader
using (StringReader str = new StringReader(sbCsv.ToString()))
{
using (CsvReader csv = new CsvReader(str, true))
{
int fieldCount = csv.FieldCount;
string[] headers = csv.GetFieldHeaders();
while (csv.ReadNextRecord())
{
for (int i = 0; i < fieldCount; i++)
{
// Do Work
}
}
}
}
}
You might be able to adapt this solution to reading chunks of a file - e.g. as you read through the StreamReader, assign different "chunks" to a Collection of StringBuilder objects and also pre-pend the header row if you want it.
Try to use CachedCSVReader instead of CSVReader and MoveTo(long recordnumber), MoveToStart etc. methods.

How to append data to a .xls file through Selenium WebDriver

I want to append data to a TestData.xls.
TestData.xls already contains data for my scripts. I am reading this data in program, processing it and result-Pass/Fail is decided on this processing.
I want to write back this results to next column in TestData.xls
I have tried like below,
for(int i=0;i<rows-1;i++)
{
WritableWorkbook wkb = Workbook.createWorkbook(new File("E://Testing//testing Tools//Selenium//TestData//TestData.xls"));
WritableSheet sh = wkb.createSheet("Agent",0);
WritableFont f = new WritableFont(WritableFont.ARIAL);
WritableCellFormat cf = new WritableCellFormat(f);
sh.addCell(new Label(0,i+1,"Pass",cf));
wkb.write();
wkb.close();
}
But it deletes all data previously available in TestData.xls
Then i tried as TestData1.xls but data is not written at correct position and it is partial.
Now I want to append data to next available column of TestData.xls without erasing previous data.
Please tell me how to append data through Selenium Webdriver
For a Starter to this question : This has nothing to do with Selenium WebDriver.
You are trying to insert value to a particular location in xls.
Try below code may be it it useful to you.
`public static void writeReport(String readFileName, String readSheetName, String result, int row,int col) throws BiffException, IOException, RowsExceededException, WriteException
{
File fileWrite = new File(readFileName);
Workbook in = Workbook.getWorkbook(fileWrite);
WritableWorkbook writable_workbook = Workbook.createWorkbook(fileWrite, in);
WritableSheet writable_sheet = writable_workbook.getSheet(readSheetName);
writable_sheet.addCell(new Label(col, row , result));
writable_workbook.write();
writable_workbook.close();
}`

How to convert file name with path to short file name (DOS style) in Adobe AIR?

How to convert file name with path to short file name (DOS style) in Adobe AIR?
For example convert next path
"C:\Program Files\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe"
to
"C:\PROGRA~1\COMMON~1\ADOBEA~1\VERSIONS\1.0\RESOUR~1\ADOBEA~1.EXE"
Is there any algorithm?
Assuming your text portion is a string variable, you can split it by using "\" as delimiter. Then, you will have an array which you can use to check if each block is longer than 8 characters. While looping the array you can chop the last characters of each long block and put ~1. Since you're in the loop, you can progressively add to a temporary variable all these changes which will give you the final edited result at the end.
The only part that's a bit tricky is to pay attention to .exe part at the end.
So, if I were you, I'd start reading on String.split(), String.substring(), for loop, arrays
Here's my handy method that does this below:
public static string GetShortPathName(string path)
{
string[] arrPath = path.Split(System.IO.Path.DirectorySeparatorChar);
path = arrPath[0]; // drive
// skip first, ( drive ) and last program name
for (int i = 1; i < arrPath.Length - 1; i++)
{
string dosDirName = arrPath[i];
if (dosDirName.Count() > 8)
{
dosDirName = dosDirName.Substring(0, 6) + "~1";
}
path += System.IO.Path.DirectorySeparatorChar + dosDirName;
}
// include program name if any
path += System.IO.Path.DirectorySeparatorChar + arrPath[arrPath.Length - 1];
return path;
}