I am facing issue while writing the data to excel file.
I am using apache POI 4.1.2 version library.
Below is the sample code.
try {
outputStream = new FileOutputStream(EXCEL_FILE_PATH);
} catch (Exception e) {
System.out.println("Exception While writing excel file " + e.getMessage());
}
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("FileCompare");
Row row = sheet.createRow(0);
Cell cellfilename = row.createCell(0);
cellfilename.setCellValue("File Name");
Cell cellfilename1 = row.createCell(1);
cellfilename1.setCellValue("Difference in File 1");
Cell cellfilenam2 = row.createCell(2);
cellfilenam2.setCellValue("Difference in File 2");
for (int diffcol = 1; diffcol < 3; diffcol++) {
for (int i = 1; i < 57; i++) {
Row rows = sheet.createRow(i);
// System.out.println("Difference Coln number " + diffcol);
Cell diffcell = rows.createCell(diffcol);
diffcell.setCellValue("abacds");
/*
* Cell diffcell2 = row.createCell(2); diffcell2.setCellValue("abacds");
*/
}
}
try {
workbook.write(outputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
outputStream.flush();
outputStream.close();
workbook.close();
}
In this only last column cells is getting saved in excel file , previous cells are kept as blank.
Kindly help and let me know if I am doing something wrong?
Not sure about the actual api but I think you inner loop should create columns and your outer one should create rows like this
for (int row=1:row<57;row++)
{
Row rows = sheet.createRow(row);
for (int diffCol = 1; diffCol < 3; difCol++)
{
Cell diffcell = rows.createCell(diffcol);
diffcell.setCellValue("abacds");
}
}
The problem is that inside your loop you're always using sheet.createRow(i) to retrieve the row you need, but as the docs says (docs that are written not so clear, actually) this method is always recreating a brand new & empty row, deleting the existing one (if a row at that i-position was already present).
It means that each iteration of yuor loop is actually deleting previous rows creating brand new rows: at the end only rows created by the last iteration are surviving!
To solve you're problem, use sheet.createRow(i) only one time in order to create the row at i-position and then only use sheet.getRow(i) to retreive it.
So replace (in your code) the following wrong line
Row rows = sheet.createRow(i);
with the following code
Row row = sheet.getRow(i);
if (row == null) row = sheet.createRow(i);
where new row is created only if it does not already exist!
And you're done, it works like a charm!
I am trying to write my test results/data to excel at runtime for which I have written the below code. I am not getting any error while compiling this code however the results are not getting written in this. Can someone help me out with the problem?
public void WritetoExcel(String filepath, String OrderID) throws IOException
{
FileInputStream ExcelFile = new FileInputStream(filepath);
System.out.println(filepath);
ExcelWBook = new XSSFWorkbook(ExcelFile);
System.out.println("WorkBook Sucessfully");
ExcelWSheet = ExcelWBook.getSheetAt(0);
System.out.println("Sheet Sucessfully");
Iterator<Row> rowIterator= ExcelWSheet.iterator();
int RowNum =0;
while (rowIterator.hasNext())
{
Row row=rowIterator.next();
RowNum++;
}
try
{
Row = ExcelWSheet.createRow(RowNum);
Iterator<Cell> cellIterator=Row.iterator();
Cell = Row.getCell(0);
if (Cell==null)
{
Cell=Row.createCell(0);
Cell.setCellValue(OrderID);
}
else
{
Cell.setCellValue(OrderID);
}
FileOutputStream fileOut = new FileOutputStream(filepath);
ExcelWBook.write(fileOut);
fileOut.flush();
fileOut.close();
}
catch (Exception e )
{
throw (e);
}
}
I was going to make this a comment, but it is too long.
There are a few comments I can make about your code.
First, it seems you are iterating through and counting rows that exist in the sheet. Then you are creating a new row at that index. Since a spreadsheet could have missing rows, this will only work for a very specific type of spreadsheet. That is, one which has no missing rows, and you always want to add the next row in the next empty spot. Instead of:
Iterator<Row> rowIterator= ExcelWSheet.iterator();
int RowNum =0;
while (rowIterator.hasNext())
{
Row row=rowIterator.next();
RowNum++;
}
try
{
Row = ExcelWSheet.createRow(RowNum);
You can just as easily use:
int rowNum = ExcelWSheet.getLastRowNum() + 1;
Row row = ExcelWSheet.createRow(rowNum);
Then you write orderId in the first column of that row. Instead of:
Iterator<Cell> cellIterator=Row.iterator();
Cell = Row.getCell(0);
if (Cell==null)
{
Cell = Row.createCell(0);
Cell.setCellValue(OrderID);
}
else
{
Cell.setCellValue(OrderID);
}
You could just use:
Cell cell = row.createCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell.setCellValue(OrderID);
In addition, for this you don't even need the iterators, but when you really need to iterate through the rows and cells of a spreadsheet it is better to use the for each syntax like this:
for (Row row : sheet) {
for (Cell cell : row) {
// do something with the cell
}
}
I am trying to create a pivot table to do cohort analysis
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);
pivotTable.addRowLabel(1);
this is giving me an error while opening the file that the file is corrupt do you want to still open the file, when I say yes and open it, the result looks fine, the only issue is the error.
I did a workaround to have a duplicate column data with different name
for ex:
say column 1 is email added a duplicate column 36 with name dup email and did as shown below, it works fine
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);
pivotTable.addRowLabel(35);
why in the first place it failed when I give both column and row label as 1.
Any help is greatly appreciated
If you set pivotTable.addRowLabel(1) using apache poi, then apache poi sets pivot field 1 only to be axisRow but it needs to be dataField too if you also want to pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1). So we neeed to correct this.
Example:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import java.io.*;
class PivotTableTest5 {
private static void setCellData(Sheet sheet) {
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Name");
cell = row.createCell(1);
cell.setCellValue("City");
for (int r = 1; r < 15; r++) {
row = sheet.createRow(r);
cell = row.createCell(0);
cell.setCellValue("Name " + ((r-1) % 4 + 1));
cell = row.createCell(1);
cell.setCellValue("City " + (int)((new java.util.Random().nextDouble() * 3)+1) );
}
}
public static void main(String[] args) {
try {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
//Create some data to build the pivot table on
setCellData(sheet);
XSSFPivotTable pivotTable = sheet.createPivotTable(
new AreaReference(new CellReference("A1"), new CellReference("B15")), new CellReference("H5"));
//Count the second column. This needs to be second column a data field.
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);
//Use second column as row label
pivotTable.addRowLabel(1);
//Apache poi sets pivot field 1 (second column) only to be axisRow but it needs to be dataField too.
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(1).setDataField(true);
FileOutputStream fileOut = new FileOutputStream("PivotTableTest5.xlsx");
wb.write(fileOut);
fileOut.close();
wb.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am trying to write ResultSet to Excel (*.xlsx) Table using Apache Poi.
Invalid Table Object Error in Office Excel
However, even though it writes the Excel file without any error, when I try to open it in Office Excel 2013, it shows an error and removes the table object to give only plain data view.
Here is the rough Sample Code using this example:
public static void writeExcel(ResultSet rs, int sqliteRowCount, String dir) {
System.out.println("Writing Excel(*.xlsx) File...");
XSSFWorkbook workbook = null;
try {
if (rs != null) {
// Get ResultSet MetaData
ResultSetMetaData rsmd = rs.getMetaData();
// Number of columns
int numColumns = rsmd.getColumnCount();
// Number of rows
// + 1 for headers
int numRows = sqliteRowCount + 1;
workbook = new XSSFWorkbook();
// Create Excel Table
XSSFSheet sheet = workbook.createSheet("Text");
XSSFTable table = sheet.createTable();
table.setDisplayName("Test");
CTTable cttable;
cttable = table.getCTTable();
// Style configurations
CTTableStyleInfo style = cttable.addNewTableStyleInfo();
style.setName("TableStyleMedium16");
style.setShowColumnStripes(false);
style.setShowRowStripes(true);
// Set Table Span Area
AreaReference reference = new AreaReference(new CellReference(0, 0), new CellReference(numRows - 1, numColumns - 1));
cttable.setRef(reference.formatAsString());
cttable.setId(1);
cttable.setName("Test");
cttable.setDisplayName("Test");
cttable.setTotalsRowCount(numRows);
cttable.setTotalsRowShown(false);
// Create Columns
CTTableColumns columns = cttable.addNewTableColumns();
columns.setCount(numColumns);
// Create Column, Row, Cell Objects
CTTableColumn column;
XSSFRow row;
// Add Header and Columns
XSSFRow headerRow = sheet.createRow(0);
for (int i = 0; i < numColumns; i++) {
column = columns.addNewTableColumn();
column.setName("Column" + (i + 1));
column.setId(i + 1);
headerRow.createCell(i).setCellValue(rsmd.getColumnLabel(i + 1));
}
// Write each row from ResultSet
int rowNumber = 1;
while (rs.next()) {
row = sheet.createRow(rowNumber);
for (int y = 0; y < numColumns; y++) {
row.createCell(y).setCellValue(rs.getString(y + 1));
}
rowNumber++;
}
// Set AutoFilter
CTAutoFilter fltr = CTAutoFilter.Factory.newInstance();
fltr.setRef((new AreaReference(new CellReference(0, 0), new CellReference(numRows - 1, numColumns - 1))).formatAsString());
cttable.setAutoFilter(fltr);
// sheet.setAutoFilter(CellRangeAddress.valueOf((new AreaReference(new CellReference(0, 0), new CellReference(numRows - 1, numColumns - 1))).formatAsString()));
// Freeze Pan
sheet.createFreezePane(0, 1, 0, 2);
}
} catch (SQLException ex) {
System.out.println("SQL Error while writing Excel file!");
} finally {
try {
// Let's write the excel file now
if (workbook != null) {
String excelDir = dir + File.separator + "workbook.xlsx";
try (final FileOutputStream out = new FileOutputStream(excelDir)) {
workbook.write(out);
}
}
} catch (IOException ex) {
System.out.println("IO Error while writing Excel summary file!");
}
}
}
I know something is wrong with my code, but can't figure it out.
Any idea, why this is happening, where would be potential mistake in my code.
Update 1:
Table XML file in Excel archive if created using Apache POI
<?xml version="1.0" encoding="UTF-8"?>
<table displayName="Test" ref="A1:B881" id="1" name="Test" totalsRowCount="881" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" totalsRowShown="0"><autoFilter ref="A1:B881"/><tableColumns count="2"><tableColumn name="ID" id="1"/><tableColumn name="Name" id="2"/><tableStyleInfo name="TableStyleMedium2" showColumnStripes="true" showRowStripes="true"/></table>
Table XML file in Excel archive if table created manually
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" id="1" name="Table1" displayName="Table1" ref="A1:B881" totalsRowShown="0"><autoFilter ref="A1:B881"/><tableColumns count="2"><tableColumn id="1" name="ID"/><tableColumn id="2" name="Name"/></tableColumns><tableStyleInfo name="TableStyleLight9" showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0"/></table>
In addition, if I open the Excel archive, it does not have a theme folder in the one created by Apache POI but it is present in the one create manually in Office Excel. Strange.
Update 2:
Sample executable code (Using Netbeans):
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package apachepoi_exceltest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyleInfo;
/**
*
*/
public class ApachePOI_ExcelTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String outputDir = "Your Local Directory Here";
// TODO code application logic here
HashMap<String, String> dataMap = new HashMap<>();
dataMap.put("ID 1", "Dummy Name 1");
dataMap.put("ID 2", "Dummy Name 2");
dataMap.put("ID 3", "Dummy Name 3");
dataMap.put("ID 4", "Dummy Name 4");
writeExcel(dataMap, outputDir);
}
private static void writeExcel(HashMap<String, String> dataMap, String outputDir) {
System.out.println("Writing Excel(*.xlsx) Summary File...");
XSSFWorkbook workbook = null;
try {
// Number of columns
int numColumns = 2; // ID and Name
// Number of rows
int numRows = dataMap.size() + 1; // +1 for header
// Create Workbook
workbook = new XSSFWorkbook();
// Create Excel Table
XSSFSheet sheet = workbook.createSheet("Summary");
XSSFTable table = sheet.createTable();
table.setDisplayName("Test");
CTTable cttable;
cttable = table.getCTTable();
// Style configurations
CTTableStyleInfo style = cttable.addNewTableStyleInfo();
style.setName("TableStyleMedium16");
style.setShowColumnStripes(false);
style.setShowRowStripes(true);
// Set Tabel Span Area
AreaReference reference = new AreaReference(new CellReference(0, 0), new CellReference(numRows - 1, numColumns - 1));
cttable.setRef(reference.formatAsString());
cttable.setId(1);
cttable.setName("Test");
cttable.setDisplayName("Test");
cttable.setTotalsRowCount(numRows);
cttable.setTotalsRowShown(false);
// Create Columns
CTTableColumns columns = cttable.addNewTableColumns();
columns.setCount(numColumns);
// Create Column, Row, Cell Objects
CTTableColumn column;
XSSFRow row;
// Add ID Header
column = columns.addNewTableColumn();
column.setName("Column" + (1));
column.setId(1);
// Add Name Header
column = columns.addNewTableColumn();
column.setName("Column" + (1));
column.setId(1);
// Add Header Row
XSSFRow headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("ID");
headerRow.createCell(1).setCellValue("Name");
int rowNumber = 1;
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
String id = entry.getKey();
String name = entry.getValue();
row = sheet.createRow(rowNumber);
row.createCell(0).setCellValue(id);
row.createCell(1).setCellValue(name);
rowNumber++;
}
// Set Filter (Below three lines code somehow not working in this example, so setting AutoFilter to WorkSheet)
// CTAutoFilter fltr = CTAutoFilter.Factory.newInstance();
// fltr.setRef((new AreaReference(new CellReference(0, 0), new CellReference(numRows - 1, numColumns - 1))).formatAsString());
// cttable.setAutoFilter(fltr);
sheet.setAutoFilter(CellRangeAddress.valueOf((new AreaReference(new CellReference(0, 0), new CellReference(numRows - 1, numColumns - 1))).formatAsString()));
// Freeze First Row as header Row
sheet.createFreezePane(0, 1, 0, 2);
} catch (Exception ex) {
System.out.println("Error while writing Excel summary file!");
} finally {
try {
// Lets write the Excel File Now
if (workbook != null) {
String excelDir = outputDir + File.separator + "workbook.xlsx";
try (final FileOutputStream out = new FileOutputStream(excelDir)) {
workbook.write(out);
}
}
} catch (IOException ex) {
System.out.println("IO Error while writing Excel summary file!");
}
}
}
}
Libraries Used:
ooxml-schemas-1.1.jar
poi-3.11-beta2-20140822.jar
poi-ooxml-3.11-beta2-20140822.jar
xmlbeans-2.6.0.jar
What's wrong with your code is a presence of a single line.
"cttable.setTotalsRowCount(numRows);"
Remove it and everything will work.
If in doubt, compare the XML definitions of some working table created manually in Excel and the definitions created with Apache POI
I had the same issue.
Digging deeply, I found that for some table XML data in the XLSX package, Excel is changing a single > to > after performing the repair. The XML from POI makes sense (use < and > to surround XML elements) so I have no idea why Microsoft chooses to break it.
If its the same case for you, I'd not worry too much about it.
If you want to see if you have this particular difference:
Create XLSX with POI
Repair XLSX with Excel and save to new file
Open both files with ZIP editor (e.g. 7Zip)
Find xl/tables/table1.xml
Export both XML files (POI and Excel-repaired)
Diff the files
You have not created your table correctly.
Check:
Did you create header columns in cttable?
Did you create the same header columns through cell.setCellValue?
Remove empty first header column(POI BUG) at the end
CTTable().getTableColumns().removeTableColumn(0);
Put debug into XSSFTable.class, method updateHeaders().
If your table is not created properly, then
XSSFRow row = sheet.getRow(headerRow);
will be NULL in
/**
* Synchronize table headers with cell values in the parent sheet.
* Headers <em>must</em> be in sync, otherwise Excel will display a
* "Found unreadable content" message on startup.
*/
#SuppressWarnings("deprecation")
public void updateHeaders(){
XSSFSheet sheet = (XSSFSheet)getParent();
CellReference ref = getStartCellReference();
if(ref == null) return;
int headerRow = ref.getRow();
int firstHeaderColumn = ref.getCol();
XSSFRow row = sheet.getRow(headerRow);
if (row != null && row.getCTRow().validate()) {
int cellnum = firstHeaderColumn;
for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnArray()) {
XSSFCell cell = row.getCell(cellnum);
if (cell != null) {
col.setName(cell.getStringCellValue());
}
cellnum++;
}
}
}
I am currently doing a program in Java that will run several tests and generate a report right after in excel. I was able to read and write through excel and the results of Passed or Failed are displayed in Results column. I was able to write these in excel but by supplying a default value on the cell (e.g. default) so the code will just overwrite it. I would like to write a comment on the Comment column, but I do not know how to write in a null cell. Here is a screenshot of the report I am generating (the link of the image available) and the code for reading and writing in excel as well.
FileInputStream fileInputStream = new FileInputStream("ReportExcel.xls");
HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
HSSFSheet worksheet = workbook.getSheetAt(0);
fileInput csvInputFile = new fileInput();
String[] sReturnValue = csvInputFile.arrayReturnSingleValue("fileInput.csv");
if (prodnameresult.equals(prodname) ){
Pass++;
totalResult++;
System.out.println ("Testcase1: Branding-Customised Product Name is PASSED");
//Harold's Input
HSSFRow row = worksheet.getRow(1);
HSSFCell cell = row.getCell((short) 4);
cell.setCellValue("Passed");
}
else{
Fail++;
totalResult++;
System.out.println("Testcase1: Branding-Customised Product Name is FAILED");
//assertEquals(prodnameresult.equals(prodname), true);
//Harold's Input
HSSFRow row = worksheet.getRow(1);
HSSFCell cell = row.getCell((short) 4);
cell.setCellValue("Failed");
}
//Harold's Input
FileOutputStream os = new FileOutputStream("ReportExcel.xls");
workbook.write(os);
os.close();
}
Report:
http://i47.tinypic.com/2s1lsfc.png
I don't have access to the report, but to answer to your question, if your cell is null you should create it and not get it as following:
HSSFCell cell = row.getCell((short) 4);
if(cell == null)
cell = row.createCell((short) 4);
cell.setCellValue("Passed");
You should maybe re-apply the Style to the Cell if it had a different one from the row.