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();
}
}
Related
I'm running the following code with Apache POI 4.1.2:
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(0);
cell.setCellValue("Cell one");
XSSFCellStyle style = wb.createCellStyle();
Color green = new Color(20, 230, 18);
style.setFillForegroundColor(new XSSFColor(green, new DefaultIndexedColorMap()));
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell.setCellStyle(style);
cell = row.createCell(1);
cell.setCellValue("cell two");
Color red = new Color(200, 30, 18);
style.setFillForegroundColor(new XSSFColor(red, new DefaultIndexedColorMap()));
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell.setCellStyle(style);
File outFile = new File(OUTPUT_DIR + "colors.xlsx");
outFile.getParentFile().mkdirs();
try (OutputStream fileOut = new FileOutputStream(outFile)) {
wb.write(fileOut);
}
wb.close();
the output document ha both cells with red background: it seems that setting red background on second cell has the effect of overwriting the first cell background color.
If I set the background only on the first cell, the background color is correctly set to green.
How can I solve this?
The color is not stored in the cell but in the cell style. So you need creating as much cell styles as colors are needed.
But also don't simply create a cell style for each cell. There are Excel limits for maximun number of unique cell formats/cell styles. If that limit gets exceeded then the workbook gets corrupt.
So on workbook level create as much cell styles as needed. Then apply those cell styles while filling cell values into the sheet.
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import java.util.List;
import java.util.ArrayList;
public class CreateExcelDifferentCellColors {
public static void main(String[] args) throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook();
// on workbook level create as much CellStyles as needed
XSSFCellStyle greenCellStyle = workbook.createCellStyle();
java.awt.Color green = new java.awt.Color(20, 230, 18);
greenCellStyle.setFillForegroundColor(new XSSFColor(green, new DefaultIndexedColorMap()));
greenCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
XSSFCellStyle redCellStyle = workbook.createCellStyle();
java.awt.Color red = new java.awt.Color(200, 30, 18);
redCellStyle.setFillForegroundColor(new XSSFColor(red, new DefaultIndexedColorMap()));
redCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
XSSFSheet sheet = workbook.createSheet();
List<Number> numbers = new ArrayList<Number>();
numbers.add(12); numbers.add(-12); numbers.add(12.1); numbers.add(-12.1); numbers.add(12.123); numbers.add(-12.123);
int r = 0;
for (Number number : numbers) {
XSSFRow row = sheet.createRow(r++);
XSSFCell cell = row.createCell(0);
cell.setCellValue(number.doubleValue());
if (number.doubleValue() < 0d) {
cell.setCellStyle(redCellStyle);
} else {
cell.setCellStyle(greenCellStyle);
}
}
FileOutputStream out = new FileOutputStream("./CreateExcelDifferentCellColors.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
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 am using apache poi for populating an excel file,my requirement is to protect the cells i have defined and the rest of the cells in the excel will be as it is.I am using sheet.protectSheet("") in this operation.But it is making the desired portion locked as well as the rest of the cells in the excel locked also.Is my requirement feasible ?? i am posting my code ,
public class ExcelLockStyle {
public static void main(String a[]) throws IOException{
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = (HSSFSheet)workbook.createSheet("worksheet");
sheet.protectSheet("password");
CellStyle lockedStyle = workbook.createCellStyle();
lockedStyle.setLocked(true);
CellStyle defaultStyle = workbook.createCellStyle();
defaultStyle.setLocked(false);
// tried to make the rest of the cell as it is , but not working
for(Row row : sheet){
for(Cell mycell : row){
mycell.setCellStyle(defaultStyle);
}
}
// Create a header row
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("locked");
cell.setCellStyle(lockedStyle);
sheet.autoSizeColumn(0);
cell = row.createCell(1);
cell.setCellValue("this cell unlocked");
cell.setCellStyle(defaultStyle);
sheet.autoSizeColumn(1);
cell = row.createCell(2);
cell.setCellValue("this column unlocked");
cell.setCellStyle(defaultStyle);
sheet.autoSizeColumn(2);
defaultStyle.setWrapText(true);
// sets any auto-generated cells in this column to unlocked
sheet.setDefaultColumnStyle(3, defaultStyle);
sheet.setDefaultColumnStyle(4, defaultStyle);
sheet.setDefaultColumnStyle(5, defaultStyle);
sheet.setDefaultColumnStyle(6, defaultStyle);
sheet.setDefaultColumnStyle(7, defaultStyle);
FileOutputStream fileOut = new FileOutputStream("D://doc.xls");
workbook.write(fileOut);
fileOut.close();
}
}
I want read only excel sheet after creating it using Apache POI HSSF. How can I do that?
A detailed description can be found here:
http://systeminetwork.com/article/locking-cells-hssf
Basically you have to assign your cells a custom CellStyle with CellStyle.setLocked(true)
Edited
Hi Gaurav,
here is the complete and working code:
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("sheet1");
/* password required for locks to become effective */
sheet.protectSheet("secretPassword");
/* cell style for locking */
CellStyle lockedCellStyle = workbook.createCellStyle();
lockedCellStyle.setLocked(true);
/* cell style for editable cells */
CellStyle unlockedCellStyle = workbook.createCellStyle();
unlockedCellStyle.setLocked(false);
/* cell which will be locked */
Cell lockedCell = sheet.createRow(0).createCell(0);
lockedCell.setCellValue("Hi, I'm locked...");
lockedCell.setCellStyle(lockedCellStyle);
/* unlocked cell */
Cell unlockedCell = sheet.createRow(1).createCell(0);
unlockedCell.setCellValue("Just edit me...");
unlockedCell.setCellStyle(unlockedCellStyle);
OutputStream out = new FileOutputStream("sample.xls");
workbook.write(out);
out.flush();
out.close();
Here is some tested code that works in making the specific cell readonly. Based on your comment in #Thomas Weber's answer.
This sets an initial value in a cell, then it uses a data constraint to ensure that fixed value cannot be modified by the user in Excel. Try it out.
HSSFWorkbook workBook = new HSSFWorkbook ();
HSSFSheet sheet1 = workBook.createSheet();
HSSFRow row1 = sheet1.createRow(10);
HSSFCell cell1 = row1.createCell(0);
cell1.setCellValue("text: The new line which should be locked"); // SETTING INITIAL VALUE
HSSFCell displayNameCell = cell1;
String[] displayNameList = new String[]{"text: The new line which should be locked"}; //ADDING SAME VALUE INTO A STRING ARRAY AS THE RESTRICTED VALUE
DVConstraint displayNameConstraint = DVConstraint.createExplicitListConstraint(displayNameList);
CellRangeAddressList displayNameCellRange = new CellRangeAddressList(displayNameCell.getRowIndex(),displayNameCell.getRowIndex(),displayNameCell.getColumnIndex(),displayNameCell.getColumnIndex());
HSSFDataValidation displayNameValidation = new HSSFDataValidation(displayNameCellRange,displayNameConstraint);
displayNameValidation.createErrorBox("Not Applicable","Cannot change the value");
displayNameValidation.setSuppressDropDownArrow(true);
displayNameCell.getSheet().addValidationData(displayNameValidation);
// Write the output to a file
FileOutputStream fileOut1 = new FileOutputStream("D:\\book.xls");
workBook.write(fileOut1);
fileOut1.close();
This code is based on this thread http://osdir.com/ml/user-poi.apache.org/2009-07/msg00056.html
new File("/path/to/file.xls").setReadOnly();
How can I rotate the text within an HSSFCell class of Apache POI?
Use HSSFCellStyle, that class has a method called setRotation(short rotation) which will rotate the text. All you do is apply the cell style to a cell:
HSSFCellStyle myStyle = workbook.createCellStyle();
myStyle.setRotation((short)90);
HSSFCell c = row.createCell(columnNumber);
c.setCellStyle(myStyle);
CellStyle cssVertical = wb.createCellStyle();
cssVertical.setFont(f);
cssVertical.setRotation((short)90);
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
XSSFRow row = sheet.createRow(1);
XSSFCell cell = row.createCell(1);
XSSFCellStyle cs = workbook.createCellStyle();
cs.setRotation((short) 90); // set text rotation
cs.getStyleXf().setApplyAlignment(true); // <<< Important
cell.setCellValue("Vertical Text");
cell.setCellStyle(cs);
workbook.write(new FileOutputStream("out.xlsx"));
Apache POI 3.17, need to manually add alignment="true" attribute in cellXfs section.