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 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'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 have to write an excel File where some rows and Columns are locked and the rest is editable. I know this was asked and answered beofre, but the latest answer is from 2012 and the solution given there doesn't work anymore. Can anyone who worked with this give a solution that works now?
This is the code that was given as solution
String file = "c:\\poitest.xlsx";
FileOutputStream outputStream = new FileOutputStream(file);
Workbook wb = new XSSFWorkbook();
CellStyle unlockedCellStyle = wb.createCellStyle();
unlockedCellStyle.setLocked(false);
Sheet sheet = wb.createSheet();
sheet.protectSheet("password");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("TEST");
cell.setCellStyle(unlockedCellStyle);
wb.write(outputStream);
outputStream.close();
The effect now is a sheet that is locked completely.
You wrote, you'd like to lock certain cells and the default should be unlocked, but your code actually unlocks a given cell.
So I go for your original request and have kind of a quick hack as I haven't found a decent method on a quick view to set a whole range of columns:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
public class XSSFLockTest {
public static void main(String args[]) throws Exception {
XSSFWorkbook wb = new XSSFWorkbook();
CellStyle unlockedCellStyle = wb.createCellStyle();
unlockedCellStyle.setLocked(false);
CellStyle lockedCellStyle = wb.createCellStyle();
lockedCellStyle.setLocked(true);
XSSFSheet sheet = wb.createSheet();
CTCol col = sheet.getCTWorksheet().getColsArray(0).addNewCol();
col.setMin(1);
col.setMax(16384);
col.setWidth(9.15);
col.setStyle(unlockedCellStyle.getIndex());
sheet.protectSheet("password");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("TEST");
cell.setCellStyle(lockedCellStyle);
FileOutputStream outputStream = new FileOutputStream("bla.xlsx");
wb.write(outputStream);
outputStream.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();
}
}
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.