I need to store numeric in number category (right click->Catergory=number). I have tried using the below code, but it saves in general format.
String valueAsString = "2345";
HSSFCell cellE1 = row1.createCell((short) 4);
cellE1.setCellValue(new BigDecimal(valueAsString).doubleValue());
You need to set a cell style to the cell, which formats it as you want. Something like
Worbook wb = new HSSFWorkbook();
DataFormat fmts = wb.getCreationHelper().createDataFormat();
// Cell Styles apply to the whole workbook, only create once
CellStyle numericStyle = wb.createCellStyle();
numericStyle.setDataFormat(fmts.getFormat("0")); // Format string
....
// Apply to the cells
Row r = sheet.createRow(0);
Cell c = r.createCell(0); // A1
c.setCellStyle(numericStyle);
c.setCellValue(Double.parseDouble("12345"));
Related
I need to update existing cell value by adding new lines to it during testing through selenium. I am not able to figure out code to update exising data using POI. When I tried to add using New Line Character, it is overwriting existing data. Please provide solution to add value to existing cell data on new line.
Below is the code what I have for new Line comment
try (OutputStream fileOut = new FileOutputStream("MyFile.xls")) {
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet");
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
cell.setCellValue("This is first line and \n this is second line");
CellStyle cs = wb.createCellStyle();
cs.setWrapText(true);
cell.setCellStyle(cs);
row.setHeightInPoints((2*sheet.getDefaultRowHeightInPoints()));
sheet.autoSizeColumn(2);
wb.write(fileOut);
Cell cell2 = row.getCell(1);
cell2.setCellValue(" \n this is third line");
CellStyle cs2 = wb.createCellStyle();
cs2.setWrapText(true);
cell2.setCellStyle(cs2);
row.setHeightInPoints((2*sheet.getDefaultRowHeightInPoints()));
sheet.autoSizeColumn(2);
wb.write(fileOut);
}catch(Exception e) {
System.out.println(e.getMessage());
}
I am generating excel sheets using Apache POI. When selecting a cell to edit the background of that cell becomes black. I have shared my code and a screenshot of the excel sheet. I didn't set the background to black from anywhere. I have struggled to solve this error for several hours. If anyone know how to solve this please help me.
public static void writeSummaryToExcel(int rowNumber, int columnNumber, String workBookName, String sheetName,
int sheetColumnSize, Map<String, List<CommonDto>> appDataMap,
List<CommonDto> summaryData) {
log.info("AppSummarySheetGenerator - writeSummaryToExcel() called");
PropertyTemplate propertyTemplate = new PropertyTemplate();
int rowCount = rowNumber;
int columnCount = columnNumber;
try {
File file = new File(workBookName);
// initialing workbook and sheet
workbook = CommonExcelUtils.getWorkbook(file, workBookName);
Sheet sheet = CommonExcelUtils.getWorkbookSheet(workbook, sheetName, sheetColumnSize, false);
Row row;
Cell cell;
if (workbook != null && sheet != null) {
//sheet setting up to first sheet
workbook.setSheetOrder(sheet.getSheetName(), 0);
// cell styles
CellStyle fontRightAlignStyle = workbook.createCellStyle();
fontRightAlignStyle.setAlignment(HorizontalAlignment.RIGHT);
Font boldFont = workbook.createFont();
boldFont.setBold(true);
boldFont.setFontHeightInPoints((short) 12);
CellStyle totalLCellStyle = getCommonTotalCellStyle(boldFont);
totalLCellStyle.setAlignment(HorizontalAlignment.LEFT);
CellStyle totalRCellStyle = getCommonTotalCellStyle(boldFont);
totalRCellStyle.setAlignment(HorizontalAlignment.RIGHT);
CellStyle appCategoryStyle = workbook.createCellStyle();
appCategoryStyle.setFont(boldFont);
appCategoryStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
appCategoryStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.index);
appCategoryStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);
//other code
}
private static CellStyle getCommonTotalCellStyle(Font boldFont) {
CellStyle commonTotalCellStyle = workbook.createCellStyle();
commonTotalCellStyle.setFont(boldFont);
commonTotalCellStyle.setBorderBottom(BorderStyle.MEDIUM);
commonTotalCellStyle.setBorderTop(BorderStyle.MEDIUM);
commonTotalCellStyle.setBorderLeft(BorderStyle.MEDIUM);
commonTotalCellStyle.setBorderRight(BorderStyle.MEDIUM);
commonTotalCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
commonTotalCellStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
return commonTotalCellStyle;
}
Screenshot of the excel sheet
The only reason I am aware of that this may happen is if there is a cell style applied to the cell which has a fill background color set but either not has a fill pattern set or has a no-fill-pattern set. Then the fill background color gets visible if the cell is in edit mode.
Complete example to test:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class CreateExcelCellBackgroudColor {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("./Excel.xlsx") ) {
CellStyle style = workbook.createCellStyle();
//style.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
//style.setFillBackgroundColor(IndexedColors.BLACK.getIndex());
style.setFillBackgroundColor((short)0);
//style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillPattern(FillPatternType.NO_FILL);
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellStyle(style);
workbook.write(fileout);
}
}
}
Here cell A1 gets black when in edit mode.
Why is that?
In Excel the cell interiors have pattern fill. There fill foreground color is the color of the pattern and fill background color is the color behind the pattern. If there is a fill background color set but not a pattern, then the background color may get visible.
So the problem is not in the code you have shown. Have a look whether you set CellStyle.setFillBackgroundColor somewhere. But maybe the problem is in the source file already. If so, then the source file probably is not created by Excel.
In my case I need to protect single cell, to achieve this initially I used HSSFCellStyle and setLocked(true) and protect the sheet using Sheet.protectSheet("password"). This will protect non empty cell also so I am using DataValidation with single option, It is working as expected but it allows to delete the cell content without validation.Below is my sample code.Thanks in advance for your help.
String errorBoxTitle = "Warning";
String errorBoxMessage = "Invalid Data";
String [] valueArr = {"cellValue"};
CellRangeAddressList cellValueAddress = new CellRangeAddressList(row.getRowNum(), row.getRowNum(), cell.getColumnIndex(), cell.getColumnIndex());
DVConstraint cellValueConstraint = DVConstraint.createExplicitListConstraint(valueArr);
DataValidation cellValueValidation = new HSSFDataValidation(cellValueAddress , cellValueConstraint );
cellValueValidation .setSuppressDropDownArrow(true);
cellValueValidation .createErrorBox(errorBoxTitle, errorBoxMessage);
cellValueValidation .setEmptyCellAllowed(false);
sheet.addValidationData(cellValueValidation );
A cell either can be locked or not locked. If it is locked, then it cannot be changed and also not be deleted. If a cell is not locked, then of course it also can be deleted. So since data validation needs to be used in not locked cells, data validation is not an option to protect against deleting.
If the goal is to have only some cells locked when the sheet is protected but most of the cells shall be not locked, then the only way is creating a cell style having setLocked(false) set and applying that cell style to all cells which shall be not locked. That is because it is the default in Excel that cells are locked when the sheet is protected.
If new cells in whole columns shall be not locked, then this notLocked cell style can be set as the default column style.
In the following example only the header cells A1:C1 and all cells in columns greater than C are locked. The cells in A2:C4 are not locked because the notLocked cell style is applied to that cells. Also the empty cells in columns A:C for rows greater than 4 are not locked because the notLocked cell style is applied as the default column style for columns A:C.
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
public class CreateExcelDefaultColumnStyleNotLocked {
public static void main(String[] args) throws Exception {
//Workbook workbook = new XSSFWorkbook(); String filePath = "./CreateExcelDefaultColumnStyleNotLocked.xlsx";
Workbook workbook = new HSSFWorkbook(); String filePath = "./CreateExcelDefaultColumnStyleNotLocked.xls";
CellStyle notLocked = workbook.createCellStyle();
notLocked.setLocked(false);
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = null;
for (int c = 0; c < 3; c++) {
cell = row.createCell(c);
cell.setCellValue("Col " + (c+1));
}
for (int r = 1; r < 4; r++) {
row = sheet.createRow(r);
for (int c = 0; c < 3; c++) {
cell = row.createCell(c);
cell.setCellValue(r * (c+1));
cell.setCellStyle(notLocked);
}
}
sheet.setDefaultColumnStyle(0, notLocked);
sheet.setDefaultColumnStyle(1, notLocked);
sheet.setDefaultColumnStyle(2, notLocked);
sheet.protectSheet("");
FileOutputStream out = new FileOutputStream(filePath);
workbook.write(out);
out.close();
workbook.close();
}
}
I want to make the header row of my excel uneditable using poi.
I got various solutions around the internet which say to firstly do sheet.protectSheet("password") which ultimately makes entire sheet uneditable and then loop through all cells which can be editable and set cellStyle for them as cellStyle.setLocked(false).
In my case since the excel just contains headers and rest of the rows will be filled up by the user I can't make the entire sheet uneditable, I just want the headers to be uneditable by the user. How can I achieve this?
Using XSSF the following could be achieved:
Set a CellStyle having setLocked false as the default style for all columns. This is possible by setting a org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol element having min col 1 and max col 16384 having set that style.
Then take out row 1 from using that style by setting CustomFormat true for that row. So it does not use the default style for all columns. Additional set a CellStyle having setLocked true as the default style for that row. This is possible by getting a org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow element from that row and set CustomFormat and S(style) there.
Result: All cells are unlocked except row 1.
Example:
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
public class CreateExcelSheetProtectOnlyFirstRow {
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
//create a CellStyle having setLocked false
CellStyle cellstyleUnprotect = workbook.createCellStyle();
cellstyleUnprotect.setLocked(false);
//create a CellStyle having setLocked true
CellStyle cellstyleProtect = workbook.createCellStyle();
cellstyleProtect.setLocked(true);
Sheet sheet = workbook.createSheet("Sheet1");
//set the CellStyle having setLocked false as the default style for all columns
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol cTCol =
((XSSFSheet)sheet).getCTWorksheet().getColsArray(0).addNewCol();
cTCol.setMin(1);
cTCol.setMax(16384);
cTCol.setWidth(12.7109375);
cTCol.setStyle(cellstyleUnprotect.getIndex());
Row row = sheet.createRow(0);
//set CustomFormat true for that row
//so it does not using the default style for all columns
//and set the CellStyle having setLocked true as the default style for that row
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow cTRow =
((XSSFRow)row).getCTRow();
cTRow.setCustomFormat(true);
cTRow.setS(cellstyleProtect.getIndex());
for (int c = 0; c < 3; c++) {
row.createCell(c).setCellValue("Header " + (c+1));
}
sheet.protectSheet("password"); // protect sheet
workbook.write(new FileOutputStream("CreateExcelSheetProtectOnlyFirstRow.xlsx"));
workbook.close();
}
}
i'm working with apache poi and XLSX file. i use xssf classes to dynamically create a spreadsheet.
i'd like to set cell's style in a for loop, but it doesn't seem to work...here's my code :
for(int i=1;i<=gc.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);i++,gc.add(GregorianCalendar.DATE, 1),righe++){
Row r = foglio.createRow(righe);
if(getDayOfWeek(gc)== 6 || getDayOfWeek(gc) == 7){
XSSFCellStyle cs1 = wb.createCellStyle();
cs1.setFillBackgroundColor(IndexedColors.YELLOW.getIndex());
cs1.setFillPattern(CellStyle.SOLID_FOREGROUND);
XSSFFont f = wb.createFont();
f.setBold(true);
f.setColor(IndexedColors.RED.getIndex());
cs1.setFont(f);
Cell c1 = r.createCell(0);
c1.setCellValue(cost.getGiorni().get(getDayOfWeek(gc)-1).getNomeGiorno());
c1.setCellStyle(cs1);
Cell c2 = r.createCell(1);
c2.setCellValue(i);
c2.setCellStyle(cs1);
}
r.createCell(0).setCellValue(cost.getGiorni().get(getDayOfWeek(gc)-1).getNomeGiorno());
r.createCell(1).setCellValue(i);
...this i just a portion of the code...
i can't understand why is not working. Seems like the cellstyle is ignored or overwrited....
any clue ?
CellStyles are per-workbook, and there's a hard limit that Excel imposes on the numbers that a file is allowed to have, so you need to make sure you create the cell style once outside the loop.
Your code would then look something like:
XSSFCellStyle cs1 = wb.createCellStyle();
cs1.setFillBackgroundColor(IndexedColors.YELLOW.getIndex());
cs1.setFillPattern(CellStyle.SOLID_FOREGROUND);
XSSFFont f = wb.createFont();
f.setBold(true);
f.setColor(IndexedColors.RED.getIndex());
cs1.setFont(f);
for(int i=1;i<=gc.getActualMaximum(GregorianCalendar.DAY_OF_MONTH) i++,gc.add(GregorianCalendar.DATE, 1),righe++){
Row r = foglio.createRow(righe);
if(getDayOfWeek(gc)== 6 || getDayOfWeek(gc) == 7){
Cell c1 = r.createCell(0);
c1.setCellValue(cost.getGiorni().get(getDayOfWeek(gc)-1).getNomeGiorno());
c1.setCellStyle(cs1);
Cell c2 = r.createCell(1);
c2.setCellValue(i);
c2.setCellStyle(cs1);
}
}
If you're having issues with the styling not looking quite as you expect, the best option is to style a cell as you want it in Excel, save the file, read that into POI, and review the cell style that Excel wrote. Sometimes, Excel can do some strange things that take some getting used to, so check what it does to work out what you need to be doing!
You can use Following method, perhaps this will resolve your problem.
public static void setCellColorAndFontColor(XSSFCell cell, IndexedColors FGcolor, IndexedColors FontColor ){
XSSFWorkbook wb = cell.getRow().getSheet().getWorkbook();
CellStyle style = wb.createCellStyle();
XSSFFont font = wb.createFont();
font.setBold(true);
font.setColor(FontColor.getIndex());
style.setFont(font);
style.setFillForegroundColor(FGcolor.getIndex());
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
cell.setCellStyle(style);
}
When you are calling this method the way should be like
setCellColorAndFontColor(cell, IndexedColors.BLACK, IndexedColors.WHITE);
will create bold & white font text color with black cell background color in the sheet.
I think the
.setFillPattern(CellStyle.SOLID_FOREGROUND);
got changed to
.setFillPattern(FillPatternType.SOLID_FOREGROUND);
this works for me:
//design settings for header row
Font headerFont = wb.createFont();
headerFont.setColor(IndexedColors.WHITE.getIndex());
CellStyle headerCellStyle = wb.createCellStyle();
headerCellStyle.setFont(headerFont);
headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headerCellStyle.setFillForegroundColor(IndexedColors.BLACK.getIndex());
headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);