I have a template XSSF sheet
I am trying to create an SXSSF file based on the template, I could create the sheet successfully, but I have a problem when I am trying to copy the styles from old sheet to the new sheet
Here is my code
FileInputStream templateFile = null;
XSSFWorkbook templateWorkbook = null;
XSSFSheet templateSheet = null;
templateFile = new FileInputStream(this.templateFilePath);
templateWorkbook = new XSSFWorkbook(templateFile);
templateSheet = templateWorkbook.getSheetAt(0);
SXSSFWorkbook sworkbook = new SXSSFWorkbook(this.largeReportCashRows);
SXSSFSheet sworksheet = (SXSSFSheet) sworkbook.createSheet();
//Create styles
CellStyle newStyle = sworkbook.createCellStyle();
//style.setFillPattern(XSSFCellStyle.FINE_DOTS );
//style.setFillBackgroundColor(IndexedColors.RED.getIndex());
CellStyle oldCellStyle = templateSheet.getRow(0).getCell(0).getCellStyle();
newStyle.cloneStyleFrom(oldCellStyle);
//SOME CODE TO CREATE ROWS & CELLS IN THE new sheet "sworksheet"
Cell cell1;
cell1.setCellStyle(newStyle);
When I execute the code, it runs and generates the sheet, but when I open it I am getting an error telling me that the sheet is corrupted, After telling Excel to fix it. It is fixed but the styles aren't working !
Please help
//to get old cell style from a cell
CellStyle oldCellStyle = sheet.getRow(0).getCell(0).getCellStyle();
//to create a new sheet in which you want to use this style
XSSFSheet sheet2 = workbook.createSheet("new2");
row=sheet2.createRow(0);
cell=row.createCell(0);
cell.setCellValue("test");
//to set old style to new cell
cell.setCellStyle(oldCellStyle);
FileOutputStream out1 = new FileOutputStream("D:\\test.xlsx");
workbook.write(out1);
out1.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 am trying following two sets of code to make part of the cell content bold/italic in streaming XSSFWorkbook that is SXSSFWorkbook. But it is not working. Any help in this regard is appreciated.
The cell content should look like following
This is sample content
try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
SXSSFSheet sheet = wb.createSheet("With Rich Text");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
XSSFFont fontPlain = (XSSFFont) wb.createFont();
XSSFFont fontBoldItalic = (XSSFFont) wb.createFont();
fontBoldItalic.setBold(true);
fontBoldItalic.setItalic(true);
XSSFFont fontItalic = (XSSFFont) wb.createFont();
fontItalic.setItalic(true);
XSSFRichTextString cell1Value= new XSSFRichTextString();
cell1Value.append("This is ");
cell1Value.append("sample ", fontBoldItalic);
cell1Value.append("content", fontItalic);
cell.setCellValue(cell1Value);
wb.write(new FileOutputStream("BoldFile.xlsx"));
} catch (IOException e) {
e.printStackTrace();
}
Also following code does the same. The cell content should look like following
Hello World
try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
SXSSFSheet sheet = wb.createSheet("With Rich Text");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
Font fontBold = wb.createFont();
fontBold.setBold(true);
String value = "Hello World";
String subValue = "World";
cell.setCellValue(value);
RichTextString rts = cell.getRichStringCellValue();
rts.applyFont(value.indexOf(subValue), value.length(), fontBold);
cell.setCellValue(rts);
wb.write(new FileOutputStream("BoldFile.xlsx"));
} catch (IOException e) {
e.printStackTrace();
}
You should always create the RichTextString using CreationHelper.createRichTextString(java.lang.String text) where CreationHelper comes from Workbook.getCreationHelper(). So you can be sure, that the created RichTextString always is of same type as the workbook. For example HSSFRichTextString from a HSSFCreationHelper, XSSFRichTextString from a XSSFCreationHelper and XSSFRichTextString for streaming SXSSF from a SXSSFCreationHelper. When created using the constructors that is not always guaranteed.
But using SXSSF there is an issue when SXSSFWorkbook uses inline strings instead of a shared strings table. This is the default in SXSSF because inline strings are better usable in the streaming approach. But Apache POI fails to create rich text content in inline strings. It only creates rich text content in the shared strings table, which is the default in Excel.
So using Workbook workbook = new SXSSFWorkbook(); no rich text cell content can be created. One needs using Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(), 100, false, true); which tells to create a SXSSFWorkbook from a new empty XSSFWorkbook, using the default rowAccessWindowSize of 100, not to use gzip compression for temporary files and to use a shared strings table.
Following code will work for all kinds of Workbook and create rich text cell content.
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
class CreateExcelRichTextString {
public static void main(String[] args) throws Exception {
//Workbook workbook = new XSSFWorkbook(); FileOutputStream out = new FileOutputStream("./Excel.xlsx");
//Workbook workbook = new HSSFWorkbook(); FileOutputStream out = new FileOutputStream("./Excel.xls");
//Workbook workbook = new SXSSFWorkbook(); FileOutputStream out = new FileOutputStream("./Excel.xlsx");
Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(), 100, false, true); FileOutputStream out = new FileOutputStream("./Excel.xlsx");
CreationHelper creationHelper = workbook.getCreationHelper();
Font font = workbook.createFont(); // default font
Font fontBold = workbook.createFont();
fontBold.setBold(true);
Font fontItalic = workbook.createFont();
fontItalic.setItalic(true);
String text = "This is some sample content.";
RichTextString richTextString = creationHelper.createRichTextString(text);
String word = "some";
int startIndex = text.indexOf(word);
int endIndex = startIndex + word.length();
richTextString.applyFont(startIndex, endIndex, fontBold);
word = "sample";
startIndex = text.indexOf(word);
endIndex = startIndex + word.length();
richTextString.applyFont(startIndex, endIndex, fontItalic);
Sheet sheet = workbook.createSheet();
sheet.createRow(0).createCell(0).setCellValue(richTextString);
workbook.write(out);
out.close();
workbook.close();
if (workbook instanceof SXSSFWorkbook) ((SXSSFWorkbook)workbook).dispose();
}
}
Conclusion: Stop thinking SXSSF is the better XSSF because of using streaming approach to save memory usage. It is not. It has disadvantages of it's own. The structure of spreadsheet application files is nothing what is good to stream bulk data in.
I try to change background color of a row, or highlight it with a different color with use of following code:
FileInputStream fis = new FileInputStream(src);
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet sheet = wb.getSheetAt(0);
r = sheet.getRow(5);
CellStyle style = wb.createCellStyle();
style.setFillForegroundColor(IndexedColors.RED.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
r.setRowStyle(style);
FileOutputStream fileOut = new FileOutputStream(excelFileName);
wb.write(fileOut);
wb.close();
fileOut.flush();
fileOut.close();
I create a style, set it to a row and after that I write it out to same file. File is modified when I execute code, but background color isn't changed.
setRowStyle(CellStyle style) doesn't work as you would expect. Taking a look at the XSSFRow source code you will not find an iteration over the cells in the row or something similar.
/**
* Applies a whole-row cell styling to the row.
* If the value is null then the style information is removed,
* causing the cell to used the default workbook style.
*/
#Override
public void setRowStyle(CellStyle style) {
if(style == null) {
if(_row.isSetS()) {
_row.unsetS();
_row.unsetCustomFormat();
}
} else {
StylesTable styleSource = getSheet().getWorkbook().getStylesSource();
XSSFCellStyle xStyle = (XSSFCellStyle)style;
xStyle.verifyBelongsToStylesSource(styleSource);
long idx = styleSource.putStyle(xStyle);
_row.setS(idx);
_row.setCustomFormat(true);
}
}
To my knowledge it is more like setting a default row style. But even when you set a row style this way afterwards created cells in this row won't get this style. Most probably you will have to do the styling cell by cell.
As per the requirement, a web form needs to be filled by taking values from a excel sheet. After filling in all the values, a numeric value gets auto populated in one of the fields in the same web form.
It is numeric value from just one web field that needs to be written in to the same excel sheet that was used to read values, code is as below:
FileInputStream file = new FileInputStream(new File(".xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet2 = workbook.getSheetAt(0);
XSSFSheet sheet3 = workbook.getSheetAt(1);
DataFormat format = workbook.createDataFormat();
String NAME = sheet2.getRow(2).getCell(1).getStringCellValue();
driver.findElement(By.id("##")).sendKeys(NAME);
like wise many cells are filled.
after that to get value from webpage into excel sheet:
String value = driver.findElement(By.id("!!")).getAttribute("value");
System.out.println(value);
The value is correctly getting printed.
using the below code the value is not getting displayed
CreationHelper createHelper = workbook.getCreationHelper();
XSSFSheet sheet4 = workbook.createSheet("new sheet");
Row row1 = sheet4.createRow((short)0);
// Create a cell and put a value in it.
Cell cell = row1.createCell(0);
cell.setCellValue(value);
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();