I create an Excel file through Apache POI XSSF and I lock the sheet with a password so user can't change the value of the first two row and first five columns (I lock the sheet and allowed editing of other cells). All work fine, the only problem is that the user can't resize the column so he can neither change nor resize the columns to read all the cells value.
Is it possible to allow column resize even if the sheet is protected?
Thi is my configuration
workbook = new XSSFWorkbook();
sheet = workbook.createSheet("Sheet1");
sheet.protectSheet("passwordExcel");
unlockedNumericStyle = workbook.createCellStyle();
unlockedNumericStyle.setLocked(false);
// Format cell for date
dateStyle = workbook.createCellStyle();
CreationHelper createHelper = workbook.getCreationHelper();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));
sheet.autoSizeColumn(1);
I read about lockFormatCell() but I don't understand if it can help me. Thanks
To be able resizing the column size while sheet is protected, you will need setting XSSFSheet.lockFormatColumns to false.
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
public class CreateExcelXSSFProtectedSheet {
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
CreationHelper createHelper = workbook.getCreationHelper();
CellStyle unlockedNumericStyle = workbook.createCellStyle();
unlockedNumericStyle.setDataFormat(createHelper.createDataFormat().getFormat("$#,##0.00_);[Red]($#,##0.00)"));
unlockedNumericStyle.setLocked(false);
CellStyle dateStyle = workbook.createCellStyle();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(1);
cell.setCellValue("some data");
row = sheet.createRow(1);
cell = row.createCell(1);
cell.setCellValue(-123456789.0123456);
cell.setCellStyle(unlockedNumericStyle);
row = sheet.createRow(2);
cell = row.createCell(1);
cell.setCellValue(new java.util.Date());
cell.setCellStyle(dateStyle);
((XSSFSheet)sheet).lockFormatColumns(false);
sheet.protectSheet("passwordExcel");
sheet.autoSizeColumn(1);
FileOutputStream out = new FileOutputStream("CreateExcelXSSFProtectedSheet.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
I need to create an XL sheet using Apache POI with some values which are long numeric for ex:1234567891011.
When i use below sample code to generate the excel sheet, the data is stored in form of Scientific format (1.23457E+12). But i want to store this data as a number ex. 1234567891011.00 is fine.
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("format sheet");
String str = "1234567891011";
Row row;
Cell cell;
short rowNum = 0;
short colNum = 0;
row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(str);
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
I tried to set the cell format to Numeric as below code but doesnt work.
row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(str);
dateCell1.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
double converted = new Double(str);
dateCell1.setCellValue(converted);
Please tell if any way possible to do it.
Excel is using number format General per default. This switches to scientific format if needed. That means if cell width is too small or numeric value is too big.
So do using a cell style having a special number format 0.00 or 0.
Example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
class CreateExcelBigDecimal {
public static void main(String[] args) throws Exception {
//Workbook workbook = new XSSFWorkbook(); String filePath = "./Excel.xlsx";
Workbook workbook = new HSSFWorkbook(); String filePath = "./Excel.xls";
DataFormat format = workbook.createDataFormat();
CellStyle numberCellStyle = workbook.createCellStyle();
numberCellStyle.setDataFormat((short)8);
numberCellStyle.setDataFormat(format.getFormat("0.00"));
Sheet sheet = workbook.createSheet();
Cell cell = sheet.createRow(0).createCell(0);
double value = 1234567891011d;
cell.setCellValue(value);
cell.setCellStyle(numberCellStyle);
sheet.setColumnWidth(0, 20*256);
FileOutputStream out = new FileOutputStream(filePath);
workbook.write(out);
out.close();
workbook.close();
}
}
That leads to showing 1234567891011.00 in cell A1.
Leave the cell as String type and format your number java side.
long yourLongNumber = 1234567891011;
String strLong = String.format("%d", yourLongNumber);
//out: "1234567891011"
I create an Excel file through Apache POI XSSF and I lock the sheet with a password so user can't change the value of the first two row and first five columns (I lock the sheet and allowed editing of other cells). All work fine, the only problem is that the user can't resize the column so he can neither change nor resize the columns to read all the cells value.
Is it possible to allow column resize even if the sheet is protected?
Thi is my configuration
workbook = new XSSFWorkbook();
sheet = workbook.createSheet("Sheet1");
sheet.protectSheet("passwordExcel");
unlockedNumericStyle = workbook.createCellStyle();
unlockedNumericStyle.setLocked(false);
// Format cell for date
dateStyle = workbook.createCellStyle();
CreationHelper createHelper = workbook.getCreationHelper();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));
sheet.autoSizeColumn(1);
I read about lockFormatCell() but I don't understand if it can help me. Thanks
To be able resizing the column size while sheet is protected, you will need setting XSSFSheet.lockFormatColumns to false.
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
public class CreateExcelXSSFProtectedSheet {
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
CreationHelper createHelper = workbook.getCreationHelper();
CellStyle unlockedNumericStyle = workbook.createCellStyle();
unlockedNumericStyle.setDataFormat(createHelper.createDataFormat().getFormat("$#,##0.00_);[Red]($#,##0.00)"));
unlockedNumericStyle.setLocked(false);
CellStyle dateStyle = workbook.createCellStyle();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(1);
cell.setCellValue("some data");
row = sheet.createRow(1);
cell = row.createCell(1);
cell.setCellValue(-123456789.0123456);
cell.setCellStyle(unlockedNumericStyle);
row = sheet.createRow(2);
cell = row.createCell(1);
cell.setCellValue(new java.util.Date());
cell.setCellStyle(dateStyle);
((XSSFSheet)sheet).lockFormatColumns(false);
sheet.protectSheet("passwordExcel");
sheet.autoSizeColumn(1);
FileOutputStream out = new FileOutputStream("CreateExcelXSSFProtectedSheet.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
I used POI and tried to arrange one entire column. But only the way I found is arrange individual cell. Although I found sheet.setDefaultColumnStyle() and tried to use this function, it doesn't work at all.
could you let me know the way of using setDefaultColumnStyle() or another way.
below code is my code to arrange individual cell.
xlsxFile = new File("data.xlsx");
wb = new XSSFWorkbook();
cellStyle = wb.createCellStyle();
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
row = sheet1.createRow(0);
cell = row.createCell(1);
cell.setCellValue("name");
cell.setCellStyle(cellStyle);
My english skill is a little awkward. Thank you for reading. If there is anything weird, please let me know.
This seems to be an bug in Apache POI. There are two issues:
First: After using Sheet.setDefaultColumnStyle with a style which defines alignments, POI does not set applyAlignment="true" in the xf element's tag in styles.xml. But it should, because only that will cause Excel to apply the alignments from that style to new cells.
Second: POI itself does not apply this style to new cells in that column. It should set s="1", where 1 is the style number, in the corresponding c tag of Sheet1.xml.
So we have to workaround:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import java.io.FileOutputStream;
import java.io.IOException;
class CenteredColumn {
public static void main(String[] args) {
try {
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet1");
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
sheet.setDefaultColumnStyle(1, cellStyle);
//Workaround 1: We set setApplyAlignment(true) into the `xf` element's tag in styles.xml.
//This causes Excel applying alignments from this style to new cells in that column.
for (int i = 0; i < ((XSSFWorkbook)wb).getStylesSource().getNumCellStyles(); i++) {
if (((XSSFWorkbook)wb).getStylesSource().getStyleAt(i).equals(cellStyle)) {
((XSSFWorkbook)wb).getStylesSource().getCellXfAt(i).setApplyAlignment(true);
}
}
Row row = sheet.getRow(0);
if (row == null) row = sheet.createRow(0);
Cell cell = row.getCell(1);
if (cell == null) cell = row.createCell(1);
cell.setCellValue("name");
//Workaround 2: We set the cellStyle to the new cell because POI will not do this itself.
cell.setCellStyle(cellStyle);
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
wb.write(fileOut);
} catch (IOException ioex) {
}
}
}
I've been using Apache POI for some time to read existing Excel 2003 files programmatically. Now I have a new requirement to create entire .xls files in-memory (still using Apache POI) and then write them to a file at the end. The only problem standing in my way is the handling of cells with dates.
Consider the following code:
Date myDate = new Date();
HSSFCell myCell;
// code that assigns a cell from an HSSFSheet to 'myCell' would go here...
myCell.setCellValue(myDate);
When I write the workbook containing this cell out to a file and open it with Excel, the cell is displayed as a number. Yes, I do realize that Excel stores its 'dates' as the number of days since January 1 1900 and that is what the number in the cell represents.
QUESTION: What API calls can I use in POI to tell it that I want a default date format applied to my date cell?
Ideally I want the spreadsheet cell to be displayed with the same default date format that Excel would have assigned it if a user had manually opened the spreadsheet in Excel and typed in a cell value that Excel recognized as being a date.
http://poi.apache.org/spreadsheet/quick-guide.html#CreateDateCells
CellStyle cellStyle = wb.createCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(
createHelper.createDataFormat().getFormat("m/d/yy h:mm"));
cell = row.createCell(1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
To set to default Excel type Date (defaulted to OS level locale /-> i.e. xlsx will look different when opened by a German or British person/ and flagged with an asterisk if you choose it in Excel's cell format chooser) you should:
CellStyle cellStyle = xssfWorkbook.createCellStyle();
cellStyle.setDataFormat((short)14);
cell.setCellStyle(cellStyle);
I did it with xlsx and it worked fine.
This example is for working with .xlsx file types. This example comes from a .jsp page used to create a .xslx spreadsheet.
import org.apache.poi.xssf.usermodel.*; //import needed
XSSFWorkbook wb = new XSSFWorkbook (); // Create workbook
XSSFSheet sheet = wb.createSheet(); // Create spreadsheet in workbook
XSSFRow row = sheet.createRow(rowIndex); // Create the row in the spreadsheet
//1. Create the date cell style
XSSFCreationHelper createHelper = wb.getCreationHelper();
XSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(
createHelper.createDataFormat().getFormat("MMMM dd, yyyy"));
//2. Apply the Date cell style to a cell
//This example sets the first cell in the row using the date cell style
cell = row.createCell(0);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
In addition to #BlondeCode answer, here are the list of all available formats that you can get with
creationHelper.createDataFormat().getFormat((short) index)
0 = "General"
1 = "0"
2 = "0.00"
3 = "#,##0"
4 = "#,##0.00"
5 = ""$"#,##0_);("$"#,##0)"
6 = ""$"#,##0_);Red"
7 = ""$"#,##0.00_);("$"#,##0.00)"
8 = ""$"#,##0.00_);Red"
9 = "0%"
10 = "0.00%"
11 = "0.00E+00"
12 = "# ?/?"
13 = "# ??/??"
14 = "m/d/yy"
15 = "d-mmm-yy"
16 = "d-mmm"
17 = "mmm-yy"
18 = "h:mm AM/PM"
19 = "h:mm:ss AM/PM"
20 = "h:mm"
21 = "h:mm:ss"
22 = "m/d/yy h:mm"
23-36 = reserved
37 = "#,##0_);(#,##0)"
38 = "#,##0_);Red"
39 = "#,##0.00_);(#,##0.00)"
40 = "#,##0.00_);Red"
41 = "(* #,##0);(* (#,##0);(* "-");(#)"
42 = "("$"* #,##0_);("$"* (#,##0);("$"* "-");(#)"
43 = "(* #,##0.00_);(* (#,##0.00);(* "-"??);(#)"
44 = "("$"* #,##0.00_);("$"* (#,##0.00);("$"* "-"??);(#_)"
45 = "mm:ss"
46 = "[h]:mm:ss"
47 = "mm:ss.0"
48 = "##0.0E+0"
49 = "#"
And from index 164, there are your custom patterns
To know the format string used by Excel without having to guess it: create an excel file, write a date in cell A1 and format it as you want. Then run the following lines:
FileInputStream fileIn = new FileInputStream("test.xlsx");
Workbook workbook = WorkbookFactory.create(fileIn);
CellStyle cellStyle = workbook.getSheetAt(0).getRow(0).getCell(0).getCellStyle();
String styleString = cellStyle.getDataFormatString();
System.out.println(styleString);
Then copy-paste the resulting string, remove the backslashes (for example d/m/yy\ h\.mm;# becomes d/m/yy h.mm;#) and use it in the http://poi.apache.org/spreadsheet/quick-guide.html#CreateDateCells code:
CellStyle cellStyle = wb.createCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("d/m/yy h.mm;#"));
cell = row.createCell(1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
I am writing my answer here because it may be helpful to other readers, who might have a slightly different requirement than the questioner here.
I prepare an .xlsx template; all the cells which will be populated with dates, are already formatted as date cells (using Excel).
I open the .xlsx template using Apache POI and then just write the date to the cell, and it works.
In the example below, cell A1 is already formatted from within Excel with the format [$-409]mmm yyyy, and the Java code is used only to populate the cell.
FileInputStream inputStream = new FileInputStream(new File("Path to .xlsx template"));
Workbook wb = new XSSFWorkbook(inputStream);
Date date1=new Date();
Sheet xlsMainTable = (Sheet) wb.getSheetAt(0);
Row myRow= CellUtil.getRow(0, xlsMainTable);
CellUtil.getCell(myRow, 0).setCellValue(date1);
WHen the Excel is opened, the date is formatted correctly.
This code sample can be used to change date format. Here I want to change from yyyy-MM-dd to dd-MM-yyyy. Here pos is position of column.
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class Test{
public static void main( String[] args )
{
String input="D:\\somefolder\\somefile.xlsx";
String output="D:\\somefolder\\someoutfile.xlsx"
FileInputStream file = new FileInputStream(new File(input));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> iterator = sheet.iterator();
Cell cell = null;
Row row=null;
row=iterator.next();
int pos=5; // 5th column is date.
while(iterator.hasNext())
{
row=iterator.next();
cell=row.getCell(pos-1);
//CellStyle cellStyle = wb.createCellStyle();
XSSFCellStyle cellStyle = (XSSFCellStyle)cell.getCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(
createHelper.createDataFormat().getFormat("dd-MM-yyyy"));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d=null;
try {
d= sdf.parse(cell.getStringCellValue());
} catch (ParseException e) {
// TODO Auto-generated catch block
d=null;
e.printStackTrace();
continue;
}
cell.setCellValue(d);
cell.setCellStyle(cellStyle);
}
file.close();
FileOutputStream outFile =new FileOutputStream(new File(output));
workbook.write(outFile);
workbook.close();
outFile.close();
}}