Updating value of cells in Excel with Java Apache POI - java

I am trying to update an existing Excel with Apache POI.
The thing is, I have an excel having in its 3rd column telephone numbers, and I want to correct them to the specific format using if-statements.
But I cannot write to the file.
Here is the code I am using:
public void readingExcel(String fileName) throws Exception {
try (FileInputStream file = new FileInputStream(new File(fileName))) {
HSSFWorkbook workbook = new HSSFWorkbook(file);
HSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
int counter = 0;
for (Row row : sheet) {
int columnIndex = 2;
row = CellUtil.getRow(counter, sheet);
Cell cell = CellUtil.getCell(row, columnIndex);
if (formatter.formatCellValue(cell).length() == 8)
cell.setCellValue("+216" + formatter.formatCellValue(cell));
if (formatter.formatCellValue(cell).length() == 11 && formatter.formatCellValue(cell).startsWith("216"))
cell.setCellValue("+" + formatter.formatCellValue(cell));
counter++;
}
FileOutputStream outFile =new FileOutputStream(new File(fileName));
workbook.write(outFile);
outFile.close();
}
}
And I am getting this error
org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:181)
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:140)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:302)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:398)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:379)
at excelapp.myClass.readingExcel(myClass.java:50)
at excelapp.myClass.<init>(myClass.java:41)
at excelapp.ExcelApp.main(ExcelApp.java:26)
The thing is that it is really important for today, and I am getting really stuck on updating the values of that column :-/ anyone has an idea? I think I'm writing the wrong way..

Related

zip file instead of an excel file when using XSSFWorkbook in java how do I open this

I am trying to write an excel file using java. I'm looking for just simply a column with one username per row right now, and then will build upon this later once I understand what is going a bit better. I get a zip file instead of the expected excel file, and it contains docProps, _rels, xl, and [Content_Types].xml. I don't understand how to open this zip file as though it is an excel file. I have not had luck finding the answer as all the tutorials I see show it to be a straight forward excel file, not a zip file. Is it a configuration I'm missing or is it to do with linux?
Here's my code, and what I end up with:
private void createExcelSheet(Assignment assignment) throws FileNotFoundException {
String excelFilePath = Configuration.DIRECTORY_ROOT+"/tests/"+assignment.getAssn_number()+"/gradebook-"+assignment.getAssn_number();
int rowNum = 0;
int col = 0;
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet spreadsheet = workbook.createSheet(assignment.getAssn_number()+" Grades ");
XSSFRow row = spreadsheet.createRow(rowNum);
Cell cell;
for (User user : userService.getUsers() ) {
row = spreadsheet.createRow(rowNum);
cell = row.createCell(rowNum);
cell.setCellValue(user.getStudent_id());
rowNum++;
}
try (FileOutputStream fos = new FileOutputStream(excelFilePath)) {
workbook.write(fos);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

How to add columns to an existing large excel file using SXSSF Apache POI?

I am working with a large excel file ( larger than 40 Mb , more than 100k rows and 50 columns ). I am successfully reading it using POI ( 3.10.1 version ) event stream and then doing some calculation and storing result into a List.
Now I have to append this List as a column in the same file. In this part I am facing issue.
I have tried to achieve this by using the below code
FileInputStream excelFile = new FileInputStream(new File(pathToFile));
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet datatypeSheet = workbook.getSheetAt(0); // Get first sheet
Iterator<Row> iterator = datatypeSheet.iterator();
int i=0;
while (iterator.hasNext()) { // Loop over each row
Row currentRow = iterator.next();
Cell cell = currentRow.createCell(currentRow.getLastCellNum());
cell.setCellType(Cell.CELL_TYPE_STRING);
if(currentRow.getRowNum() == 0)
cell.setCellValue("OUTPUT-COLUMN"); // set column header for the new column
else {
cell.setCellValue(list.get(i)); // list contains the output to populate in new column
i++;
}
}
FileOutputStream fos = new FileOutputStream(new File(pathToOutput));
workbook.write(fos);
fos.close();
It is working fine with smaller files But the issue is that I am getting Out of memory for the larger files. Now I tried to modify this and use SXSSF in place of XSFF to get over the memory issue (See below code). But while testing even for smaller files I am getting output file same as the input file.
FileInputStream excelFile = new FileInputStream(new File(pathToFile));
XSSFWorkbook xwb = new XSSFWorkbook(inputStream);
inputStream.close();
SXSSFWorkbook wb = new SXSSFWorkbook(xwb,100);
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.getSheetAt(0);
Iterator<Row> iterator = datatypeSheet.iterator();
int i=0;
while (iterator.hasNext()) { // Loop over each row
Row currentRow = iterator.next();
Cell cell = currentRow.createCell(currentRow.getLastCellNum());
cell.setCellType(Cell.CELL_TYPE_STRING);
if(currentRow.getRowNum() == 0)
cell.setCellValue("OUTPUT-COLUMN"); // set column header for the new column
else {
cell.setCellValue(list.get(i)); // list contains the output to populate in new column
i++;
}
}
FileOutputStream fos = new FileOutputStream(new File(pathToOutput));
wb.write(fos);
fos.close();
Using a db is not suitable in my use case and i want to avoid using a temporary data structure to hold data for writing due to memory constraint.
Is there a way to write in output workbook while streaming ? Here is the code that I am using to read using POI Streaming API
private class ExcelData implements SheetContentsHandler {
LinkedHashMap<Strin, String> rowMap;
public void startRow(int rowNum) {
}
public void endRow(int rowNum) {
// Process the row
// Handle write to output workbook ??
}
public void cell(String cellReference, String formattedValue,
XSSFComment comment) {
// Save current row in rowMap ( column name => cell value )
}
public void headerFooter(String text, boolean isHeader, String tagName)
{
}
}
It is not possible to add column to existing workbook using POI SXSSF. It only allows addition of new rows.
The only solution is to read the existing workbook and write to a new workbook with the added column.
To achieve this we can store the rows in a data structure or database in the endrow() method and then use the persisted data to write a new workbook.

How can I load CSV file into Excel sheet using Java

I have an Excel spreadsheet that has the first sheet designated for the raw data. There are 3 more sheets that are coded to transform and format the data from the raw sheet. The fifth sheet has the final output.
How can I use Java:
load the data from the CSV file into the first sheet of the excel file?
save the data from the 5th sheet into the new CSV file.
Also, if the original CSV has thousands of rows, I assume the multi-sheet transformations would take some time before the 5th sheet gets all the final data - is there a way to know?
I would follow this approach:
Load the specific .csv file and prepare to read it with Java
Load the .xlsx file and change it according to your requirements and the data that you get from the .csv file. A small example of how an excel file is changed with Apache POI can be seen below:
try
{
HashMap<Integer, ArrayList<String>> fileData; // This for example keeps the data from the csv in this form ( 0 -> [ "Column1", "Column2" ]...)
// Working with the excel file now
FileInputStream file = new FileInputStream("Data.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(file); // getting the Workbook
XSSFSheet sheet = workbook.getSheetAt(0);
Cell cell = null;
AtomicInteger row = new AtomicInteger(0);
fileData.forEach((key, csvRow) ->
{
//Update the value of the cell
//Retrieve the row and check for null
HSSFRow sheetRow = sheet.getRow(row);
if(sheetRow == null)
{
sheetRow = sheet.createRow(row);
}
for (int i = 0; i < csvRow.size(); i++)
{
//Update the value of cell
cell = sheetRow.getCell(i);
if(cell == null){
cell = sheetRow.createCell(i);
}
cell.setCellValue(csvRow.get(i));
}
});
file.close();
FileOutputStream outFile =new FileOutputStream(new File("Data.xlsx"));
workbook.write(outFile);
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
After saving the .xlsx file, you can create the .csv file by following this question.

Read Column values from excel file using selenium java

I am trying to read column values from excel file which looks like this
This is my code for reading excel file
Xls_Reader d = new Xls_Reader("C:\\TestData.xlsx");
System.out.println(d.getRowCount("sheetname"));
String s1 = String.valueOf(d.getCellData("TC03", "Contract_ID",3));
s1 =(int)Double.parseDouble(s1) + "";
System.out.println(s1);
in this code i am able to get record of one row. But i need to print all the Row value.
Please suggest.
What Jars you are using for this approach?
I have following code to read data from excel using apache poi -
public static void main(String args[]) throws IOException
{
FileInputStream fis = new FileInputStream(new File("your_file.xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook(fis); // XSSFWorkbook for .xlsx file
XSSFSheet sheet = workbook.getSheetAt(0); // open sheet 1
Iterator<Row> rowIterator = sheet.iterator();
// Traversing over each row of XLSX file
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
if(row.getRowNum()!=0) // skip title row
{
Iterator cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = (Cell) cellIterator.next();
System.out.print(cell.getStringCellValue() + "\t");
}
}
}
}
Note :- In my case cell in excel sheet formatted as text you can change cell.getStringCellValue() method as per your data.
This method will be print all sheet of your excel document:
public static void GetEmail() throws IOException{
InputStream in = new FileInputStream("C:/path to your doc");
HSSFWorkbook wb = new HSSFWorkbook(in);
ExcelExtractor extractor = new ExcelExtractor(wb);
extractor.setFormulasNotResults(false); // Read formulas
extractor.setIncludeSheetNames(false);
String text = extractor.getText();
System.out.println(text);
}

Converting an excel file string to imaginary excel file

I am reading an excel file as a text, and I am posting this string to server. However, I couldn't convert this string to a proper data structure to use it as an input for apache poi functions without creating a temp file in the file system. What I want to do is this;
Excel String -> An Excel File Object (imaginary) -> Reading data from this imaginary file
I don't want to create a temp file every time someone tries to upload an excel file.
I tried something like this;
InputStream stream = new ByteArrayInputStream(OntologyContentTxt.getBytes(StandardCharsets.UTF_8));
HSSFWorkbook wb = new HSSFWorkbook(stream);
HSSFSheet sheet=wb.getSheetAt(0);
HSSFRow row;
HSSFCell cell;
Iterator rows = sheet.rowIterator();
while (rows.hasNext())
{
row=(HSSFRow) rows.next();
Iterator cells = row.cellIterator();
while (cells.hasNext())
{
cell=(HSSFCell) cells.next();
if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING)
{
System.out.print(cell.getStringCellValue()+" ");
}
else if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC)
{
System.out.print(cell.getNumericCellValue()+" ");
}
}
System.out.println();
}}
But it gives me this error.
org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0xE011BDBFEFBDBFEF, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
How can I make this kind of convert?
Thanks.

Categories

Resources