currently im struggling setting a DataFormat to a specific row.
This is how my Excel Sheet looks like. Im having those 4 Columns.
Column 1 should take DataFormat Number
Column 2 & 3 should take DataFormat Date
Column 4 is ok
public static void createTableRow(Sheet sheet, List<String> EDIROWKeys, int col, CellStyle style , int lastRowNum){
if(sheet == null){
return;
}
int lastRow = lastRowNum;
int newRow = lastRow + 1;
Workbook wb = sheet.getWorkbook();
SimpleDateFormat format = new SimpleDateFormat();
CreationHelper helper = wb.getCreationHelper();
org.apache.poi.ss.usermodel.DataFormat date = wb.createDataFormat();
XSSFRow row = (XSSFRow) sheet.createRow(newRow);
if(row == null){
return;
}
int startCol = col;
for(String string : EDIROWKeys){
XSSFCell cell = row.createCell(startCol);
FOe.getFOPSessionContext().getDbContext().out().println(string);
if(style != null){
cell.setCellStyle(style);
}else {
XSSFWorkbook wbx = (XSSFWorkbook) sheet.getWorkbook();
XSSFDataFormat dataformat = wbx.createDataFormat();
XSSFCellStyle cs = wbx.createCellStyle();
if(startCol == 1){
cs.setDataFormat(dataformat.getFormat("#"));
}
cell.setCellStyle(cs);
}
cell.setCellValue(string);
startCol++;
}
return;
}
This is the Method i am using to Create my rows & Columns
https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/BuiltinFormats.html
This is the resource i was getting my DataFormats from.
I also tried applying those DataFormats with HssfDataformat to my cell - no success either.
I apperciate any helpful input :)
Solved by using setCellValue(Double);...
if(string.matches("\\d+")){
cell.setCellValue(Double.valueOf(string));
startCol++;
continue;
}
I see one possible case. If method argument style is null, new style, XSSFCellStyle cs is not applied to cell. Is cell.setCellStyle(cs) missing?
Related
This question already has answers here:
How do I resolve ClassNotFoundException?
(28 answers)
Closed 6 months ago.
I am in a learning stage of Java. I want to write a program in Java which reads one Excel file (.xlsx). This file has some columns and many rows. I want to write the data in another Excel file (.xlsx) only the condition is met not all the data from existing file.
My Excel sheet looks like below
I want to filter only those rows with broker Edelweiss and put it in another Excel sheet. I am aware how to copy all the data from one Excel to another Excel using Java. I don't know how to filter a specific row and put it in another Excel.
Here is my code.
FileInputStream file = new FileInputStream(new File("broker.xlsx"));
//Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
//Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
//For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
//Check the cell type and format accordingly
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "t");
break;
}
}
System.out.println("");
}
file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
I am getting the below error when I run Axel Richter's code which is shared below
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream
at org.apache.poi.poifs.filesystem.FileMagic.valueOf(FileMagic.java:209)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:222)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:185)
at writefile.main(writefile.java:92)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
I have included below jars in my classpath
POI_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/poi-5.2.2.jar
POI_OOXML_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/poi-ooxml-full-5.2.2.jar
XML_BEANS_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/ooxml-lib/xmlbeans-5.0.3.jar
COM_COLL_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/lib/commons-collections4-4.4.jar
COM_COMPRESS_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/ooxml-lib/commons-compress-1.21.jar
COM_CODEC_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/lib/commons-codec-1.15.jar
COM_IO_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/lib/commons-io-2.11.0.jar
COM_MATH_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/lib/commons-math3-3.6.1.jar
LOG_J4_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/lib/log4j-api-2.17.2.jar
SPARSE_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/lib/SparseBitSet-1.2.jar
COM_LOGG_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/ooxml-lib/commons-logging-1.2.jar
CURVE_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/ooxml-lib/curvesapi-1.07.jar
SLF4_LIB=$(TOP_DIR)/jar/poi-bin-5.2.2/ooxml-lib/slf4j-api-1.7.36.jar
I will make my comment an answer.
I would open the source sheet and loop through all rows in it. For each row I would get the content of the column where "Broker" is stored. Then, if that content equals "Edelweiss" I would get that row into a Java collection, a list of rows for example. After that I would write the content of that Java collection into the result sheet.
The following complete example shows this.
It contains methods to get the last filled row in a special column of a sheet and to get the last filled column in a special row of a sheet. That is to determine the used cell range of a sheet.
It also contains a method to get the headings, which maps headings to column indexes. The headings must be in first row of the used cell range of the sheet.
It also shows how to use CellUtil.copyCell to copy cells from one sheet to another.
The code is tested and works using current apache poi 5.2.2.
The first sheet of broker.xlsx looks like:
Code:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellUtil;
import java.util.Locale;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
class ExcelFilterRowsToNewWorkbook {
static int getLastFilledRow(Sheet sheet, int col) {
int lastStoredRowNum = sheet.getLastRowNum();
for (int r = lastStoredRowNum; r >= 0; r--) {
Row row = sheet.getRow(r);
if (row != null) {
Cell cell = row.getCell(col);
if (cell != null && cell.getCellType() != CellType.BLANK) return row.getRowNum();
}
}
return -1; // the sheet is empty in that col
}
static int getLastFilledColumn(Sheet sheet, int rowIdx) {
int lastStoredCellNum = sheet.getRow(rowIdx).getLastCellNum();
Row row = sheet.getRow(rowIdx);
if (row != null) {
for (int c = lastStoredCellNum; c >= 0; c--) {
Cell cell = row.getCell(c);
if (cell != null && cell.getCellType() != CellType.BLANK) return cell.getColumnIndex();
}
}
return -1; // the sheet is empty in that row
}
static Map<Integer, String> getHeadings(Sheet sheet) {
DataFormatter dataFormatter = new DataFormatter(new Locale("en", "US"));
dataFormatter.setUseCachedValuesForFormulaCells(true);
int firstRow = sheet.getFirstRowNum();
int firstCol = sheet.getRow(firstRow).getFirstCellNum();
int lastCol = getLastFilledColumn(sheet, firstRow);
Map<Integer, String> headings = new HashMap<Integer, String>();
Row row = sheet.getRow(firstRow);
if (row != null) {
for (int c = firstCol; c <= lastCol; c++) {
Cell cell = row.getCell(c);
headings.put(c, dataFormatter.formatCellValue(cell));
}
}
return headings;
}
static List<Row> filterRows(Sheet sheet, String filterHeading, String filterValue) {
int filterCol = -1;
Map<Integer, String> headings = getHeadings(sheet);
for (Map.Entry<Integer, String> entry : headings.entrySet()) {
if (entry.getValue().equals(filterHeading)) {
filterCol = entry.getKey();
break;
}
}
List<Row> rows = new ArrayList<Row>();
// add the headings row
int firstRow = sheet.getFirstRowNum();
rows.add(sheet.getRow(firstRow));
// add the fildered rows
if (filterCol > -1) {
DataFormatter dataFormatter = new DataFormatter(new Locale("en", "US"));
dataFormatter.setUseCachedValuesForFormulaCells(true);
int firstCol = sheet.getRow(firstRow).getFirstCellNum();
int lastCol = getLastFilledColumn(sheet, firstRow);
int lastRow = getLastFilledRow(sheet, firstCol);
for (int r = firstRow; r <= lastRow; r++) {
Row row = sheet.getRow(r);
if (row != null && lastCol >= filterCol) {
Cell cell = row.getCell(filterCol);
String cellContent = dataFormatter.formatCellValue(cell);
if (cellContent.equals(filterValue)) {
rows.add(row);
}
}
}
}
return rows;
}
public static void main(String[] args) throws Exception {
try (Workbook workbookSrc = WorkbookFactory.create(new FileInputStream("./broker.xlsx")) ) {
Sheet sheetSrc = workbookSrc.getSheetAt(0);
// get filtered rows
List<Row> rowsSrc = filterRows(sheetSrc, "Broker", "Edelweiss");
// add filtered rows in new workbook
try (Workbook workbookDest = WorkbookFactory.create(true);
FileOutputStream fileout = new FileOutputStream("./brokerFiltered.xlsx") ) {
Sheet sheetDest = workbookDest.createSheet();
int r = 0;
for (Row rowSrc : rowsSrc) {
Row rowDest = sheetDest.createRow(r++);
for (Cell cellSrc : rowSrc) {
Cell cellDest = rowDest.createCell(cellSrc.getColumnIndex());
CellUtil.copyCell(cellSrc,
cellDest,
new CellCopyPolicy(),
new CellCopyContext()
);
}
}
workbookDest.write(fileout);
}
}
}
}
The first sheet of brokerFiltered.xlsx then looks like:
I am trying to write out to an existing excel file. I don't want to create new rows or cells, I just want to write out the value from my array into the value at row x column y. Every time I have tried this so far I can only get it to work if I create a new row. Please help!!!
Integer columns = DataImport.columns_in_sheet[0];
Integer rowNum = learnerRow + 2;
try {
FileInputStream inp = new FileInputStream("D:/location/update.xlsx");
XSSFWorkbook wb = null;
wb = (XSSFWorkbook) WorkbookFactory.create(inp);
XSSFSheet sheet = wb.getSheetAt(0);
XSSFRow row = sheet.getRow(18);//places the start row
XSSFCell cell = null;//places the start column
cell = row.getCell(0);
//#########################################################################################
//#########################################################################################
for (int j = 0; j < exportData.length; j++) {
//sheet.createRow(rowNum+j);
//row = sheet.getRow(rowNum+j);
//row = sheet.getRow(rowNum+j);
for (int i=0; i < columns;i++){
cell.setCellType(CellType.STRING);
cell.setCellValue(exportData[j][i]);
}
}
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("D:/location/update.xlsx");
wb.write(fileOut);
fileOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
this code throws a null pointer because of row being null, I can only seem to get rid of the error by creating new rows. I am using XSSF formatting.
The logic of your code snippet is not clear. It looks not logically to me.
But to avoid NPE while using rows and cells from present sheets, one always needs check whether the row or cell was present already or needs to be new created. This is necessary because for not present rows Sheet.getRow will return null. Also Row.getCell will return null for not present cells.
So we can do:
Sheet sheet = ...
Row row = sheet.getRow(rowIdx); if (row == null) row = sheet.createRow(rowIdx);
Cell cell = row.getCell(cellIdx); if (cell == null) cell = row.createCell(cellIdx);
Now row either is a row which was already present or it is a new created row. And cell either is a cell which was already present or it is a new created cell. Neither row nor cell will be null. And at first present rows/cells will be got before they were new created if not present. So present rows and cells will not be destroyed.
The same is needed in loops:
Sheet sheet = ...
Row row;
Cell cell;
for (int rowIdx = 0; rowIdx < 10; rowIdx++) {
row = sheet.getRow(rowIdx); if (row == null) row = sheet.createRow(rowIdx);
for (int cellIdx = 0; cellIdx < 10; cellIdx++) {
cell = row.getCell(cellIdx); if (cell == null) cell = row.createCell(cellIdx);
// do something with cell
}
}
I'm trying to get the font size of the header on an excel spreadsheet but I haven't been able to get it. I tried using the following to get the size but I haven't been able to get the size. None of the following worked for me because it doesn't return the correct font size.
headerFont.getFontHeight ();
headerFont.getFontHeightInPoints ();
Any suggestion?
Below is the code that I have:
try {
FileInputStream file = new FileInputStream(new File(fileName));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(1);
int numRows = sheet.getLastRowNum() + 1;
int numCols = sheet.getRow(0).getLastCellNum();
Iterator<Row> rowIterator = sheet.iterator();
for (int i = 0; i < 1; i++) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
for (int j = 0; j < numCols; j++) {
Cell cell = cellIterator.next();
Font headerFont = workbook.createFont();
headerFontFamily = headerFont.getFontName();
headerFont.getFontHeight();
headerFont.getFontHeightInPoints();
}
}
file.close();
} catch (Exception e) {
}
You need to get the fonts from the cells. Fonts are part of the cell styles. Cell styles can be got via Cell.getCellStyle. Then the index of the used font can be got as a short via CelStyle.getFontIndex or as int via CelStyle.getFontIndexAsInt or as int via CelStyle.getFontIndex dependig of apache poi version used. The latter works using current 5.0.0 version.
Complete example:
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
class ReadExcel {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExample.xlsx"));
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
DataFormatter dataFormatter = new DataFormatter();
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String value = dataFormatter.formatCellValue(cell, evaluator);
System.out.println(value);
CellStyle style = cell.getCellStyle();
//short fontIdx = style.getFontIndex(); // depends on apache poi version
//int fontIdx = style.getFontIndexAsInt(); // depends on apache poi version
int fontIdx = style.getFontIndex(); // depends on apache poi version
Font font = workbook.getFontAt(fontIdx);
System.out.println(font.getFontName() + ", " + font.getFontHeightInPoints());
}
}
workbook.close();
}
}
Note: This only works if the cell only has one font. If the cell contains rich text strings, then there are fonts for each formatting text run. Then RichTextString needs to be got and traversed. This is much more complex and needs to be done different for HSSF and XSSF.
I am creating an excel file with apache poi the excel is generated but i can not adjust the column with according to the cell values i am posting the code what i have done so far
This is how i have created the headers in excel
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
sheet.protectSheet("password");
sheet.autoSizeColumn(15);
HSSFFont hSSFFont = wb.createFont();
hSSFFont.setFontName(HSSFFont.FONT_ARIAL);
hSSFFont.setFontHeightInPoints((short) 8);
CellStyle style = wb.createCellStyle();
/* cell style for locking */
CellStyle lockedCellStyle = wb.createCellStyle();
lockedCellStyle.setLocked(true);
HSSFRow row = null;
HSSFCell cell = null;
row = sheet.createRow(0);
int headercolumnNo = 0;
//1st Column Header for Indicator
cell = row.createCell(headercolumnNo);
cell.setCellValue(new HSSFRichTextString(listOfActiveCarrierUserHeader.get(0)));
style.setWrapText(true);
style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());
style.setFont(hSSFFont);
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
cell.setCellStyle(style);
headercolumnNo = 1;
cell = row.createCell(headercolumnNo); //2nd Column Header for Firstname
cell.setCellValue(new HSSFRichTextString(listOfActiveCarrierUserHeader.get(1)));
style.setWrapText(true);
style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());
style.setFont(hSSFFont);
cell.setCellStyle(style);
headercolumnNo = headercolumnNo + 1;
cell = row.createCell(headercolumnNo); //2nd Column Header for Firstname
cell.setCellValue(new HSSFRichTextString(listOfActiveCarrierUserHeader.get(2)));
style.setWrapText(true);
style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());
style.setFont(hSSFFont);
cell.setCellStyle(style);
headercolumnNo = headercolumnNo + 1;
and this is how i have populated the values in that excel file
for(CarrierActiveUser carrierActiveUser : listOfCarrierUser){
int columnNo = 0;
row = sheet.createRow(j + 1);
cell = row.createCell(columnNo);
if(null != carrierActiveUser.getFistName()){
cell.setCellValue(new HSSFRichTextString(carrierActiveUser.getFistName()));
lockedCellStyle.setFont(hSSFFont);
cell.setCellStyle(lockedCellStyle);
}else{
cell.setCellValue(new HSSFRichTextString(" "));
cell.setCellStyle(lockedCellStyle);
}
columnNo = columnNo + 1;
cell = row.createCell(columnNo);
if(null != carrierActiveUser.getLastName()){
cell.setCellValue(new HSSFRichTextString(carrierActiveUser.getLastName()));
lockedCellStyle.setFont(hSSFFont);
cell.setCellStyle(lockedCellStyle);
}else{
cell.setCellValue(new HSSFRichTextString(" "));
cell.setCellStyle(lockedCellStyle);
}
columnNo = columnNo + 1;
cell = row.createCell(columnNo);
if(null != carrierActiveUser.getLastName()){
cell.setCellValue(new HSSFRichTextString(carrierActiveUser.getEmailId()));
lockedCellStyle.setFont(hSSFFont);
cell.setCellStyle(lockedCellStyle);
}else{
cell.setCellValue(new HSSFRichTextString(" "));
cell.setCellStyle(lockedCellStyle);
}
Please someone help me to adjust the columns , i am new to apache poi
You can use HSSFSheet.autoSizeColumn(columnNumber) method to align the columns perfectly.
This method adjusts the column width to fit the contents, read the doc.
After setting all cell values for all columns you can use this method, in your current code call this method after for loop.
Sample code
sheet.autoSizeColumn(1);
sheet.autoSizeColumn(2);
Note - You have to do this separately for all columns which you want to be aligned and the call to sheet.autoSizeColumn(columnNumber) should be made after populating the data into the excel. Calling before populating data will not have any effect.
Actually I tried to store some data in HSSFCell using java but i got an error like
java.lang.IllegalArgumentException: The maximum length of cell contents (text) i
s 32,767 characters
at org.apache.poi.hssf.usermodel.HSSFCell.setCellValue(HSSFCell.java:559
)
at org.apache.poi.hssf.usermodel.HSSFCell.setCellValue(HSSFCell.java:533
)
at application.ExtractUI.datatoexcel(ExtractUI.java:272)
at application.ExtractUI$3.getData(ExtractUI.java:208)
at application.ExtractUI$3.handle(ExtractUI.java:198)
at application.ExtractUI$3.handle(ExtractUI.java:1)
can anyone suggest me a method to increase the cell length ie more than 32767 characters???
I used the following code for which I got the above error
public void datatoexcel(ResultSet rs) {
try {
int iter = 0;
ResultSetMetaData rmeta = rs.getMetaData();
int col = rmeta.getColumnCount();
HSSFWorkbook workbook = new HSSFWorkbook();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy HHmmss");
String pa = pth + "\\" + sdf.format(date) + ".xlsx";
System.out.println(pa);
FileOutputStream out = new FileOutputStream(new File(pa));
HSSFSheet sheet = workbook.createSheet();
HSSFRow myRow = null;
HSSFCell myCell = null;
// Font style for headers
HSSFFont boldFont = workbook.createFont();
boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
boldFont.setColor(HSSFFont.COLOR_RED);
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFont(boldFont);
while (rs.next()) {
// limit the data to 1000 anad create a new sheet
if (iter == 1000) {
sheet = workbook.createSheet();
iter = 0;
}
// Adding header to the first row
if (iter == 0) {
myRow = sheet.createRow(iter);
for (int k = 1, j = 0; k <= col && j < col; k++) {
myCell = myRow.createCell( j);
myCell.setCellValue(rmeta.getColumnName(k));
// set style to font
myCell.setCellStyle(cellStyle);
j++;
}
iter++;
}
// Adding data from 2nd Row
myRow = sheet.createRow(iter);
for (int k = 1, j = 0; k <= col && j < col; k++) {
myRow.createCell( j).setCellValue(
rs.getString(rmeta.getColumnName(k)));
j++;
}
iter++;
}
workbook.write(out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
any suggestions??
Your only option is to switch file formats. There's a hard limit in both the .xls and .xlsx file formats of 32,767 characters. Apache POI is simply enforcing the file format + Excel limit. You can see details of those limits in the Microsoft documentation, and also captured nicely in this Apache POI javadoc page
If you really need text that long, you'll need to switch to another file format such as CSV
Or you can truncate your string length to the specified maximum length minus one
private void writeIssueDataForEachRow(Issue issue, Row row, CellStyle style,
List<ColumnIndex> customFieldDefinitions) {
Cell cell = row.createCell(0);
cell.setCellValue(issue.getId()); // 編號
cell.setCellStyle(style);
cell = row.createCell(1);
cell.setCellValue(issue.getSubject()); // 主旨
cell.setCellStyle(style);
// substring 的原因是要避開 The maximum length of cell contents (text) is 32,767 characters
cell = row.createCell(2);
cell.setCellValue(StringUtils.substring(issue.getDescription(), 0, 32767)); // 敘述
cell.setCellStyle(style);
}