Append an excel sheet to another using NPOI - excel

I am trying to append the data from multiple sheets in the same workbook and append them to the first sheet.
Here's what I have been able to accomplish:
void SomeMethod()
{
HSSFWorkbook hssfwb;
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
hssfwb = new HSSFWorkbook(file);
}
var BaseSheet = workbook.GetSheetAt(0);
for (int i = 1; i < workbook.NumberOfSheets; i++)
{
AddRowsToBaseSheet(BaseSheet, workbook.GetSheetAt(i), workbook);
}
}
private void AddRowsToBaseSheet(ISheet BaseSheet, ISheet sheet, HSSFWorkbook workbook)
{
var temp = sheet.GetRowEnumerator();
while (temp.MoveNext())
{
HSSFRow sourceRow = (HSSFRow)temp.Current;
HSSFRow destinationRow = (HSSFRow)BaseSheet.CreateRow(BaseSheet.LastRowNum + 1);
CopyRow(workbook, sourceRow, destinationRow);
}
}
private void CopyRow(HSSFWorkbook workbook, IRow sourceRow, IRow destinationRow)
{
// Loop through source columns to add to new row
for (int i = 0; i < sourceRow.LastCellNum; i++)
{
// Grab a copy of the old/new cell
ICell oldCell = sourceRow.GetCell(i);
ICell newCell = destinationRow.CreateCell(i);
// If the old cell is null jump to next cell
if (oldCell == null)
{
newCell = null;
continue;
}
// Set the cell data type
newCell.SetCellType(oldCell.CellType);
// Set the cell data value
switch (oldCell.CellType)
{
case CellType.Blank:
newCell.SetCellValue(oldCell.StringCellValue);
break;
case CellType.Boolean:
newCell.SetCellValue(oldCell.BooleanCellValue);
break;
case CellType.Error:
newCell.SetCellErrorValue(oldCell.ErrorCellValue);
break;
case CellType.Formula:
newCell.SetCellFormula(oldCell.CellFormula);
break;
case CellType.Numeric:
newCell.SetCellValue(oldCell.NumericCellValue);
break;
case CellType.String:
newCell.SetCellValue(oldCell.RichStringCellValue);
break;
case CellType.Unknown:
newCell.SetCellValue(oldCell.StringCellValue);
break;
}
}
}
I might be doing a foolish mistake, or is there any other library for the same?
Converting into dataset wont work in this case as the columns are not related

Related

Apache POI : Copy data to Particular sheet at particular cell with Merged Columns in Source Sheet

Problem
How to add some part of data from source excel sheet to the destination excel sheet using Apache POI(XSSF Format)?Excel sheet contains merged columns.
Requirement:
Requirement is not only to copy the row but also to put the data into desired Excel cell(desired column) of the destination sheet.
Note
-Copying row to desired row location in destination excel sheet is achievable. Problem is to first merge the cell as per source sheet in destination sheet and then put data into desired merged excel cell.
- Merged Columns could vary in a row.
Here is the source code, half referred and half written.
public static void copyNodeFrmtSrcToDest(XSSFSheet srcSheet, XSSFSheet destSheet, XSSFRow srcRowStart,XSSFRow srcRowEnd
,XSSFRow destRowStart, int destCellStart, Map<Integer, XSSFCellStyle> styleMap){
/*Check if there is only one row to be pasted*/
int noOfRows = srcRowEnd.getRowNum() - srcRowStart.getRowNum();
/*Check if there is only one row to be pasted*/
if(noOfRows == 0)
{
/*Copy a single row*/
copyRow(srcSheet,destSheet,srcRowStart,destRowStart,destCellStart,styleMap);
return;
}
for (int i = 0;i <= noOfRows ;i++)//For every row
{
/*Get rows from source sheet and increment it*/
XSSFRow srcIntermediateRow = srcSheet.getRow(srcRowStart.getRowNum() + i);
if(destRowStart == null)
{
try {
throw new RowNotFoundError("Row has not been found in the sheet.Kindly create a row.");
} catch (RowNotFoundError e) {
e.printStackTrace();
System.out.println(e.toString());
}
}
if(i!=0)//Assuming destRowStart has been created by user of the API
{
/*Create a new row*/
destRowStart = destSheet.createRow(destRowStart.getRowNum()+1);
}
copyRow(srcSheet,destSheet,srcIntermediateRow,destRowStart,destCellStart,styleMap);
}
}
public static void copyRow(XSSFSheet srcSheet, XSSFSheet destSheet, XSSFRow srcRow, XSSFRow destRow, int destCellStart,
Map<Integer, XSSFCellStyle> styleMap) {
int count = 1;
Set<CellRangeAddress> mergedRegions = new HashSet<CellRangeAddress>();
CellRangeAddress previousMergedRegion =null;
destRow.setHeight(srcRow.getHeight());
for (int j = srcRow.getFirstCellNum(); j <= srcRow.getLastCellNum(); j++) {
int mergedDiff;
XSSFCell oldCell = srcRow.getCell(j);
XSSFCell newCell;
if(j == srcRow.getFirstCellNum()){
newCell = destRow.getCell(destCellStart);}
else
{
newCell = destRow.getCell(destCellStart + count);
}
if (oldCell != null) {
if (newCell == null) {
if(j == srcRow.getFirstCellNum()){
newCell = destRow.createCell(destCellStart);//Keeping the new cell as the first one.
copyCell(oldCell, newCell, styleMap);
}
else{
newCell = destRow.createCell(destCellStart + count);
count = count + 1;
copyCell(oldCell, newCell, styleMap);}
}
CellRangeAddress mergedRegion = getMergedRegion(srcSheet, srcRow.getRowNum(),oldCell.getColumnIndex());
if(previousMergedRegion != null && mergedRegion != null)
{
mergedDiff = mergedRegion.getLastColumn() - mergedRegion.getFirstColumn();
if(!previousMergedRegion.equals(mergedRegion))
{
destCellStart = destCellStart + mergedDiff + 1;
count = 1;
}
}
if (mergedRegion != null) {
previousMergedRegion = mergedRegion.copy();
mergedDiff = mergedRegion.getLastColumn() - mergedRegion.getFirstColumn();
CellRangeAddress newMergedRegion = new CellRangeAddress(destRow.getRowNum(),destRow.getRowNum()
,destCellStart,destCellStart + mergedDiff);
if (isNewMergedRegion(newMergedRegion, mergedRegions))
{
mergedRegions.add(newMergedRegion);
destSheet.addMergedRegion(newMergedRegion);
}
}
}
}
}
public static void copyCell(XSSFCell oldCell, XSSFCell newCell, Map<Integer, XSSFCellStyle> styleMap) {
if(styleMap != null) {
if(oldCell.getSheet().getWorkbook() == newCell.getSheet().getWorkbook()){
newCell.setCellStyle(oldCell.getCellStyle());
} else{
int stHashCode = oldCell.getCellStyle().hashCode();
XSSFCellStyle newCellStyle = styleMap.get(stHashCode);
if(newCellStyle == null){
newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
styleMap.put(stHashCode, newCellStyle);
}
newCell.setCellStyle(newCellStyle);
}
}
switch(oldCell.getCellTypeEnum()) {
case STRING:
newCell.setCellValue(oldCell.getStringCellValue());
break;
case NUMERIC:
newCell.setCellValue(oldCell.getNumericCellValue());
break;
case BLANK:
newCell.setCellValue(oldCell.getStringCellValue());
break;
case BOOLEAN:
newCell.setCellValue(oldCell.getBooleanCellValue());
break;
case ERROR:
newCell.setCellErrorValue(oldCell.getErrorCellValue());
break;
case FORMULA:
newCell.setCellFormula(oldCell.getCellFormula());
break;
default:
break;
}
}
public static CellRangeAddress getMergedRegion(XSSFSheet sheet, int rowNum, int cellNum) {
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
CellRangeAddress merged = sheet.getMergedRegion(i);
if (merged.isInRange(rowNum, cellNum)) {
return merged;
}
}
return null;
}
private static boolean isNewMergedRegion(CellRangeAddress newMergedRegion, Set<CellRangeAddress> mergedRegions)
{
if(mergedRegions.isEmpty())
{
return true;
}
return !mergedRegions.contains(newMergedRegion);
}
}
It is working fine for some testcases but not for all.

Selenium Webdriver How to select records from table by fetching Excel Input

im struggeling for below scenario.
Application displayed records of 100 suppliers in one table have three columns namely as ID,Company name and Subscription name.
i want to take input from my excel sheet say company name"xyz" and using that input i have to click on subscription name details link so application will navigates me next page.
Sample code i have created as below:
`public static void main(String[] args) throws BiffException, IOException, Exception {
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
//Workbook location
Workbook wBook = Workbook.getWorkbook(new File("C:\Users\amit.bhagwat\Documents\TestData\SampleData.xls"));
//get sheet
jxl.Sheet Sheet = wBook.getSheet(0);
//loop
for(int i=1; i<Sheet.getRows(); i++)
{
driver.get("http://206.132.42.243/Web");
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//input[#id='UserName']")).sendKeys(Sheet.getCell(0, i).getContents());
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//input[#id='Password']")).sendKeys(Sheet.getCell(1, i).getContents());
driver.findElement(By.xpath("//input[#id='Password']")).sendKeys(Sheet.getCell(1, i).getContents());
Thread.sleep(40);
driver.findElement(By.xpath("//input[#name='Login']")).click();
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//a[contains(text(),'Task')]")).click();
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//a[contains(text(),'Data Checking')]")).click();
jxl.Sheet Sheet2 = wBook.getSheet(0);
WebElement kancheck = driver.findElement(By.name("Grant & Brown"));
kancheck.click();
System.out.println(kancheck.isSelected());
driver.findElement(By.xpath("//a[contains(text(),'Data Checking')]")).sendKeys(Sheet2.getCell(1, i).getContents());
Thread.sleep(40);` enter code here
As far as I could understand, you are trying to read the file from a remote location and then read the information from it. It would be a good practice if you can use Apache POI library to read contents at run-time.
In my project, I read all the contents from an excel sheet usingApache POI library to set the values of my variables. Here is a code snippet on how i achieved it. Hopefully this will guide you to a proper solution. :)
public void readExcelDoc() throws FileNotFoundException, IOException
{
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("excelDoc//scripts.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row = null;
HSSFCell cell = null;
int rows = 0; // No of rows
// rows = sheet.getPhysicalNumberOfRows();
rows = sheet.getLastRowNum();
int cols = 2; // No of columns
int tmp = 0;
// This trick ensures that we get the data properly even if it doesn't start from first few rows
for(int i = 0; i < 10 || i < rows; i++) {
row = sheet.getRow(i);
if(row != null) {
tmp = sheet.getRow(i).getPhysicalNumberOfCells();
if(tmp > cols) cols = tmp;
}
}
int testRowNo = 0;
String rowName = "Test Name";
String columnValue = " ";
//Iterate through Row and columns here. Excluding 1st row for title names
for(int r = 1; r <= rows; r++) {
row = sheet.getRow(r);
if(row != null) {
//Browse through columns using c
for(int c = 0; c < cols; c++) {
if(c==0) //Only taking data from Cell 0; Ignoring any other inputs
{
cell = row.getCell((short)c);
try
{
if(cell.getStringCellValue().contains(rowName))
{
testRowNo =row.getRowNum();
}
if(testRowNo > 0 )
{
if(cell.getColumnIndex() == 0 && row.getRowNum() > testRowNo && cell.getStringCellValue().length() !=0)
{
try{
String cellValue = cell.getStringCellValue().toLowerCase();
//System.out.println(cellValue);
scriptType.add(cellValue);
}
catch(IllegalStateException e)
{
e.printStackTrace();
scriptType.add(cell.getStringCellValue());
}
}
}
}
catch(NullPointerException e)
{
}
}
if(c==1)
{
cell = row.getCell((short)c); //this sets the column number
if(testRowNo == 0)
{
try{
String cellValue = cell.getStringCellValue();
//System.out.println(cellValue);
columnValue = cellValue;
}
catch(IllegalStateException e)
{
String cellValue = cell.toString();
columnValue = cellValue;
}
catch(NullPointerException e)
{
String cellValue = nodata;
columnValue = cellValue;
}
}
}
if(c==2)
{
cell = row.getCell((short)c); //this sets the column number
if(testRowNo == 0)
{
try{
String cellValue = cell.getStringCellValue();
//System.out.println(cellValue);
inputParameters.put(cellValue, columnValue);
}
catch(IllegalStateException e)
{
String cellValue = cell.toString();
inputParameters.put(cellValue, columnValue);
}
catch(NullPointerException e)
{
String cellValue = nodata;
inputParameters.put(cellValue, columnValue);
}
}
}
}
}
}
System.out.println("---------The parameters set from excel are : ---------");
#SuppressWarnings("rawtypes")
Iterator iterator = inputParameters.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next().toString();
String value = inputParameters.get(key).toString();
System.out.println(key + " : " + value);
}
}

DataTable to excel conversion

I have a datagrid which populates a datatable, I want to export the DataTable to excel on click of a button. I am using MVVM for this application. So is it ok to implement the export feature in my view?
Secondly, as i am using xaml and desktop application, how do i capture the grid and its details.
Can any one suggest me some pointers? I am new to this.
Thanks,
Sagar
This is what i have done and it helped me:
private readonly ICommand m_ExportButtonClick;
private string ExcelFilePath = "";
public ICommand ExportButtonClick { get { return m_ExportButtonClick; } }
private void OnRunExport()
{
try
{
if (queryDatatable == null || queryDatatable.Columns.Count == 0)
throw new Exception("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
Excell.Application excelApp = new Excell.Application();
excelApp.Workbooks.Add();
// single worksheet
Excell._Worksheet workSheet = excelApp.ActiveSheet;
// column headings
for (int i = 0; i < queryDatatable.Columns.Count; i++)
{
workSheet.Cells[1, (i + 1)] = queryDatatable.Columns[i].ColumnName;
}
// rows
for (int i = 0; i < queryDatatable.Rows.Count; i++)
{
// to do: format datetime values before printing
for (int j = 0; j < queryDatatable.Columns.Count; j++)
{
workSheet.Cells[(i + 2), (j + 1)] = queryDatatable.Rows[i][j];
}
}
// check fielpath
if (ExcelFilePath != null && ExcelFilePath != "")
{
try
{
workSheet.SaveAs(ExcelFilePath);
excelApp.Quit();
MessageBox.Show("Excel file saved!");
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
}
}
else // no filepath is given, the file opens up and the user can save it accordingly.
{
excelApp.Visible = true;
}
}
catch (Exception ex)
{
MessageBox.Show("There is no data to export. Please check your query/ Contact administrator." + ex.Message);
}
}
#endregion
Here's an extension method to output to any DataTable to a csv (which excel can open)
Imports System.Text
Imports System.IO
Imports System.Runtime.CompilerServices
Module ExtensionMethods
<Extension()> _
Public Sub OutputAsCSV(ByVal dt As DataTable, ByVal filePath As String)
Dim sb As New StringBuilder()
'write column names to string builder
Dim columnNames As String() = (From col As DataColumn In dt.Columns Select col.ColumnName).ToArray
sb.AppendLine(String.Join(",", columnNames))
'write cell value in each row to string builder
For Each row As DataRow In dt.Rows
Dim fields As String() = (From cell In row.ItemArray Select CStr(cell)).ToArray
sb.AppendLine(String.Join(",", fields))
Next
'write string builder to file
File.WriteAllText(filePath, sb.ToString())
End Sub
End Module
Try googling around a little. This is a very common problem and has been asked a lot already. Here's a good answer from this SO question
public static void ExportToExcel<T>(IEnumerable<T> exportData)
{
Excel.ApplicationClass excel = new Excel.ApplicationClass();
Excel.Workbook workbook = excel.Application.Workbooks.Add(true);
PropertyInfo[] pInfos = typeof(T).GetProperties();
if (pInfos != null && pInfos.Count() > 0)
{
int iCol = 0;
int iRow = 0;
foreach (PropertyInfo eachPInfo in pInfos.Where(W => W.CanRead == true))
{
// Add column headings...
iCol++;
excel.Cells[1, iCol] = eachPInfo.Name;
}
foreach (T item in exportData)
{
iRow++;
// add each row's cell data...
iCol = 0;
foreach (PropertyInfo eachPInfo in pInfos.Where(W => W.CanRead == true))
{
iCol++;
excel.Cells[iRow + 1, iCol] = eachPInfo.GetValue(item, null);
}
}
// Global missing reference for objects we are not defining...
object missing = System.Reflection.Missing.Value;
// If wanting to Save the workbook...
string filePath = System.IO.Path.GetTempPath() + DateTime.Now.Ticks.ToString() + ".xlsm";
workbook.SaveAs(filePath, Excel.XlFileFormat.xlOpenXMLWorkbookMacroEnabled, missing, missing, false, false, Excel.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing);
// If wanting to make Excel visible and activate the worksheet...
excel.Visible = true;
Excel.Worksheet worksheet = (Excel.Worksheet)excel.ActiveSheet;
excel.Rows.EntireRow.AutoFit();
excel.Columns.EntireColumn.AutoFit();
((Excel._Worksheet)worksheet).Activate();
}
}

how to get last row of excel in POI and append blank row?

how to get last row of excel in POI and append blank row and write the next record after the blank row
Below is my code snippet
public class ResultSetToExcel {
private HSSFWorkbook workbook;
private HSSFSheet sheet;
private HSSFFont boldFont;
private HSSFDataFormat format;
private ResultSet resultSet;
private FormatType[] formatTypes;
public ResultSetToExcel(ResultSet resultSet, FormatType[] formatTypes, String sheetName) {
workbook = new HSSFWorkbook();
this.resultSet = resultSet;
sheet = workbook.createSheet(sheetName);
boldFont = workbook.createFont();
boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
format = workbook.createDataFormat();
this.formatTypes = formatTypes;
}
public ResultSetToExcel(ResultSet resultSet, String sheetName) {
this(resultSet, null, sheetName);
}
private FormatType getFormatType(Class _class) {
if (_class == Integer.class || _class == Long.class) {
return FormatType.INTEGER;
} else if (_class == Float.class || _class == Double.class) {
return FormatType.FLOAT;
} else if (_class == Timestamp.class || _class == java.sql.Date.class) {
return FormatType.DATE;
} else {
return FormatType.TEXT;
}
}
public void generate(OutputStream outputStream) throws Exception {
try {
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
if (formatTypes != null && formatTypes.length != resultSetMetaData.getColumnCount()) {
throw new IllegalStateException("Number of types is not identical to number of resultset columns. "
+ "Number of types: " + formatTypes.length + ". Number of columns: "
+ resultSetMetaData.getColumnCount());
}
int currentRow = 0;
HSSFRow row = sheet.createRow(currentRow);
int numCols = resultSetMetaData.getColumnCount();
boolean isAutoDecideFormatTypes;
if (isAutoDecideFormatTypes = (formatTypes == null)) {
formatTypes = new FormatType[numCols];
}
for (int i = 0; i < numCols; i++) {
String title = resultSetMetaData.getColumnName(i + 1);
writeCell(row, i, title, FormatType.TEXT, boldFont);
if (isAutoDecideFormatTypes) {
Class _class = Class.forName(resultSetMetaData.getColumnClassName(i + 1));
formatTypes[i] = getFormatType(_class);
}
}
currentRow++; // Write report rows
while (resultSet.next()) {
row = sheet.createRow(currentRow++);
for (int i = 0; i < numCols; i++) {
Object value = resultSet.getObject(i + 1);
writeCell(row, i, value, formatTypes[i]);
}
}
// Autosize columns
for (int i = 0; i < numCols; i++) {
sheet.autoSizeColumn((short) i);
}
workbook.write(outputStream);
} finally {
outputStream.close();
}
}
public void generate(File file) throws Exception {
generate(new FileOutputStream(file));
}
private void writeCell(HSSFRow row, int col, Object value, FormatType formatType) throws NestableException {
writeCell(row, col, value, formatType, null, null);
}
private void writeCell(HSSFRow row, int col, Object value, FormatType formatType, HSSFFont font)
throws NestableException {
writeCell(row, col, value, formatType, null, font);
}
private void writeCell(HSSFRow row, int col, Object value, FormatType formatType, Short bgColor, HSSFFont font)
throws NestableException {
HSSFCell cell = HSSFCellUtil.createCell(row, col, null);
if (value == null) {
return;
}
if (font != null) {
HSSFCellStyle style = workbook.createCellStyle();
style.setFont(font);
cell.setCellStyle(style);
}
switch (formatType) {
case TEXT:
cell.setCellValue(value.toString());
break;
case INTEGER:
cell.setCellValue(((Number) value).intValue());
HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
.getBuiltinFormat(("#,##0")));
break;
case FLOAT:
cell.setCellValue(((Number) value).doubleValue());
HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
.getBuiltinFormat(("#,##0.00")));
break;
case DATE:
cell.setCellValue((Timestamp) value);
HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
.getBuiltinFormat(("m/d/yy")));
break;
case MONEY:
cell.setCellValue(((Number) value).intValue());
HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, format
.getFormat("($#,##0.00);($#,##0.00)"));
break;
case PERCENTAGE:
cell.setCellValue(((Number) value).doubleValue());
HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
.getBuiltinFormat("0.00%"));
}
if (bgColor != null) {
HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.FILL_FOREGROUND_COLOR, bgColor);
HSSFCellUtil
.setCellStyleProperty(cell, workbook, HSSFCellUtil.FILL_PATTERN, HSSFCellStyle.SOLID_FOREGROUND);
}
}
public enum FormatType {
TEXT, INTEGER, FLOAT, DATE, MONEY, PERCENTAGE
}
}
And class implementing the above code
ResultSetToExcel resultSetToExcel = new ResultSetToExcel(iResultSet, csv_file_name);
int fileCount = 1;
while (true) {
boolean done = resultSetToExcel.generate(new File(csv_file_path+ csv_file_name));
if (done) break;
csv_file_name = csv_file_name + "_" + fileCount + ".xls";
fileCount++;
}
Edit:
I used below snippet
InputStream myxls = new FileInputStream("test.xls");
Workbook book = new HSSFWorkbook(myxls);
Sheet sheet = book.getSheetAt(0);
System.out.println(sheet.getLastRowNum());
But I get this error
java.io.IOException: Unable to read entire header; 0 bytes read; expected 512 bytes
The key bit is the exception is the number 0:
java.io.IOException: Unable to read entire header; 0 bytes read; expected 512 bytes
POI went to read the 512 byte header that should be at the start of the file, but found 0 bytes in the file - your file is empty.
Make sure you're passing in the correct filename to load. (You mention struts in your tag, you might not be in the directory you expected to be when running...)
Also, I'd suggest a slight improvement to your code. You have a file, and you're using the common interfaces, so you should change how you load the workbook. Instead of your current:
InputStream myxls = new FileInputStream("test.xls");
Workbook book = new HSSFWorkbook(myxls);
You'd be much better off with
Workbook book = WorkbookFactory.create(new File("test.xls"));
Loading directly from a file, rather than going via an InputStream, will give better performance and a lower memory footprint. By using the WorkbookFactory, your code can work for both XLS and XLSX files.

How to transpose sheet with POI SS/XSSF?

I am using POI XSSF API and I would like to transpose a sheet.
how can I do that?
Thanks.
Transpose, as in swap A2 with B1 and A3 with C1 (so columns become rows)?
If so, there's nothing built in, so you'd need to do a little bit of coding yourself. You'd likely want to grab a pair of cells, save the contents of one (value and style), copy the second to the first, then overwrite the second.
See the quick guide if you're not sure on all the reading/writing parts.
I was looking for the same answer and had to code it myself. I've attached my solution which is quite simple:
Determine the number of rows
Determine the maximal number of columns used
Iterator over every row, and every column
Save the Cell from that row/column into a simple list as a 'CellModel' type
Once done, iterate over all CellModels
Switch column and row index and save the CellModel into the sheet
The code I've used is:
public static void transpose(Workbook wb, int sheetNum, boolean replaceOriginalSheet) {
Sheet sheet = wb.getSheetAt(sheetNum);
Pair<Integer, Integer> lastRowColumn = getLastRowAndLastColumn(sheet);
int lastRow = lastRowColumn.getFirst();
int lastColumn = lastRowColumn.getSecond();
LOG.debug("Sheet {} has {} rows and {} columns, transposing ...", new Object[] {sheet.getSheetName(), 1+lastRow, lastColumn});
List<CellModel> allCells = new ArrayList<CellModel>();
for (int rowNum = 0; rowNum <= lastRow; rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
for (int columnNum = 0; columnNum < lastColumn; columnNum++) {
Cell cell = row.getCell(columnNum);
allCells.add(new CellModel(cell));
}
}
LOG.debug("Read {} cells ... transposing them", allCells.size());
Sheet tSheet = wb.createSheet(sheet.getSheetName() + "_transposed");
for (CellModel cm : allCells) {
if (cm.isBlank()) {
continue;
}
int tRow = cm.getColNum();
int tColumn = cm.getRowNum();
Row row = tSheet.getRow(tRow);
if (row == null) {
row = tSheet.createRow(tRow);
}
Cell cell = row.createCell(tColumn);
cm.insertInto(cell);
}
lastRowColumn = getLastRowAndLastColumn(sheet);
lastRow = lastRowColumn.getFirst();
lastColumn = lastRowColumn.getSecond();
LOG.debug("Transposing done. {} now has {} rows and {} columns.", new Object[] {tSheet.getSheetName(), 1+lastRow, lastColumn});
if (replaceOriginalSheet) {
int pos = wb.getSheetIndex(sheet);
wb.removeSheetAt(pos);
wb.setSheetOrder(tSheet.getSheetName(), pos);
}
}
private static Pair<Integer, Integer> getLastRowAndLastColumn(Sheet sheet) {
int lastRow = sheet.getLastRowNum();
int lastColumn = 0;
for (Row row : sheet) {
if (lastColumn < row.getLastCellNum()) {
lastColumn = row.getLastCellNum();
}
}
return new Pair<Integer, Integer>(lastRow, lastColumn);
}
Whereby the CellModel is a wrapper which holds the data a Cell contained (you can add more attributes if you like e.g., comments, ...):
static class CellModel {
private int rowNum = -1;
private int colNum = -1;
private CellStyle cellStyle;
private int cellType = -1;
private Object cellValue;
public CellModel(Cell cell) {
if (cell != null) {
this.rowNum = cell.getRowIndex();
this.colNum = cell.getColumnIndex();
this.cellStyle = cell.getCellStyle();
this.cellType = cell.getCellType();
switch (this.cellType) {
case Cell.CELL_TYPE_BLANK:
break;
case Cell.CELL_TYPE_BOOLEAN:
cellValue = cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_ERROR:
cellValue = cell.getErrorCellValue();
break;
case Cell.CELL_TYPE_FORMULA:
cellValue = cell.getCellFormula();
break;
case Cell.CELL_TYPE_NUMERIC:
cellValue = cell.getNumericCellValue();
break;
case Cell.CELL_TYPE_STRING:
cellValue = cell.getRichStringCellValue();
break;
}
}
}
public boolean isBlank() {
return this.cellType == -1 && this.rowNum == -1 && this.colNum == -1;
}
public void insertInto(Cell cell) {
if (isBlank()) {
return;
}
cell.setCellStyle(this.cellStyle);
cell.setCellType(this.cellType);
switch (this.cellType) {
case Cell.CELL_TYPE_BLANK:
break;
case Cell.CELL_TYPE_BOOLEAN:
cell.setCellValue((boolean) this.cellValue);
break;
case Cell.CELL_TYPE_ERROR:
cell.setCellErrorValue((byte) this.cellValue);
break;
case Cell.CELL_TYPE_FORMULA:
cell.setCellFormula((String) this.cellValue);
break;
case Cell.CELL_TYPE_NUMERIC:
cell.setCellValue((double) this.cellValue);
break;
case Cell.CELL_TYPE_STRING:
cell.setCellValue((RichTextString) this.cellValue);
break;
}
}
public CellStyle getCellStyle() {
return cellStyle;
}
public int getCellType() {
return cellType;
}
public Object getCellValue() {
return cellValue;
}
public int getRowNum() {
return rowNum;
}
public int getColNum() {
return colNum;
}
}

Resources