Changing size of cell comments in Apache POI - java

I use the following java code to successfully generate cell comments in Apache POI
public static void setComment(String text, Cell cell) {
final Map<Sheet, HSSFPatriarch> drawingPatriarches = new HashMap<Sheet, HSSFPatriarch>();
CreationHelper createHelper = cell.getSheet().getWorkbook().getCreationHelper();
HSSFSheet sheet = (HSSFSheet) cell.getSheet();
HSSFPatriarch drawingPatriarch = drawingPatriarches.get(sheet);
if (drawingPatriarch == null) {
drawingPatriarch = sheet.createDrawingPatriarch();
drawingPatriarches.put(sheet, drawingPatriarch);
}
Comment comment = drawingPatriarch.createComment(new HSSFClientAnchor(100, 100, 100, 100, (short)1, 1, (short) 10, 5));
comment.setString(createHelper.createRichTextString(text));
cell.setCellComment(comment);
}
I copied it from creating cell comments using HSSFClientAnchor in apache poi. Thank you Erik!
How can I change the size of the comment to 300 pixels width and 100 pixels height?
Thanks!

From what I can tell there's not an easy way since comment anchor points are specified by cell (column, row parameters) and offset into cell (dx, dy parameters). So you need to compute the width/height of the cells to figure out the second cell coordinates and then the offsets into that cell to make it exactly the pixel size you want.

Busy Developers' Guide to HSSF and XSSF Features
// When the comment box is visible, have it show in a 1x3 space
ClientAnchor anchor = factory.createClientAnchor();
anchor.setCol1(cell.getColumnIndex());
anchor.setCol2(cell.getColumnIndex()+1);
anchor.setRow1(row.getRowNum());
anchor.setRow2(row.getRowNum()+3);
Just change the values for setCol2 and setRow2.

You can assign a column width for any cell as follows:
sheet.setColumnWidth(0, 1000);

Related

Apache poi cell diagonal strikethrough

How can I strikethrough diagonally a cell in excel using Apache poi?
I want to get something like this:
I have tried:
cell.getCellStyle().setFillPattern(CellStyle.THIN_BACKWARD_DIAG)
but then the cell is having many diagonal lines instead of one from top right to bottom left.
Edit:
This is how I create the workbook:
Workbook workbook = new SXSSFWorkbook(SXSSFWorkbook.DEFAULT_WINDOW_SIZE);
Sheet sheet = workbook.createSheet("Test");
Then creating the columns and the rows, I don't see there any special to show.
Any idea what can I do?
Sorry for my previous answer, currently there is no diagonal border available readily in apache poi, though we can write our own custom method. You can use below method which will add a diagonal border in a cell.
public static void setDiagonal(StylesTable stylesSource, CTXf cellXtraFormating, ThemesTable theme) {
CTBorder ct = CTBorder.Factory.newInstance();
CTBorderPr pr = ct.addNewDiagonal();
ct.setDiagonalUp(true);
pr.setStyle(STBorderStyle.Enum.forInt(BorderFormatting.BORDER_THIN + 1));
int idx = stylesSource.putBorder(new XSSFCellBorder(ct, theme));
cellXtraFormating.setBorderId(idx);
cellXtraFormating.setApplyBorder(true);
}
call the above method in your class like this
CellStyle cs = workbook.createCellStyle();
StylesTable styleSource = ((XSSFWorkbook) workbook).getStylesSource();
ThemesTable theme = styleSource.getTheme();
CTXf cellXtraFormating = ((XSSFCellStyle) cs).getCoreXf();
-------your custom code---------
setDiagonal(styleSource, cellXtraFormating, theme);
cell.setCellStyle(cs);
I hope this answers your question

Using cell styles provided by the ss model in Apache POI

I trying to make the code I already wrote for an XSSF workbook compatible to both xls and xlsx. Given below a piece of code as an example.
Workbook workbook = WorkbookFactory.create(new File("F:\\JavaEE\\test.xls"));
Sheet sheet = workbook.getSheetAt(0);
short cellBorderColour = IndexedColors.GREY_80_PERCENT.getIndex();
Font font = workbook.createFont();
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
font.setColor(IndexedColors.BLUE_GREY.index);
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
cellStyle.setFont(font);
cellStyle.setBorderLeft(CellStyle.BORDER_HAIR);
cellStyle.setLeftBorderColor(cellBorderColour);
cellStyle.setBorderTop(CellStyle.BORDER_HAIR);
cellStyle.setTopBorderColor(cellBorderColour);
cellStyle.setBorderRight(CellStyle.BORDER_HAIR);
cellStyle.setRightBorderColor(cellBorderColour);
cellStyle.setBorderBottom(CellStyle.BORDER_MEDIUM);
cellStyle.setBottomBorderColor(cellBorderColour);
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
sheet.addMergedRegion(new CellRangeAddress(1, 1, 1, 4));
borderRowCells(1, 4, row, cell, cellStyle);
cell.setCellValue("Value");
FileOutputStream fos = new FileOutputStream("F:\\JavaEE\\new_test.xls");
workbook.write(fos);
//Take care of exception handling and closing of the stream.
The utility method as used by the above code to border across merged cells.
private void borderRowCells(int from, int to, Row row, Cell cell, CellStyle cellStyle) {
for (int i = from; i <= to; ++i) {
cell = row.createCell(i);
cell.setCellStyle(cellStyle);
}
}
This code is meant to apply some borders in conjunction with other styles across some merged cells.
The border across merged cells is however, not applied correctly as can be seen in the following picture.
The borders are expected to be applied starting from B2 to E2. The actual border area however, covers only from C2 to E2
The cell value Value is also not aligned center which is specified in the cell style.
How to apply this border correctly across the merged cells along with center alignment?
Also the list of colours provided by IndexedColors.COLOR_NAME.getIndex() is very limited. The list is very unlikely to fulfill the real needs of colours in different cell styles.
Can we use RGB colours in the ss model as we do in the xssf model using XSSFColor as follows?
XSSFColor commonColor = new XSSFColor(new java.awt.Color(240, 240, 240));
Or even something better/different?
PS : I'm using Apache POI 3.10.1.

Merge and align center cell using apache poi

I want to export data to excel using Apache poi. Now the problem that I am facing is that I am unable to merge rows and align them in the center.
Code for export data is:
List<LinkedHashMap<String,Object>> lstReportHeader = null;
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
//Set Header Font
HSSFFont headerFont = wb.createFont();
headerFont.setBoldweight(headerFont.BOLDWEIGHT_BOLD);
headerFont.setFontHeightInPoints((short) 12);
//Set Header Style
CellStyle headerStyle = wb.createCellStyle();
headerStyle.setFillBackgroundColor(IndexedColors.BLACK.getIndex());
headerStyle.setAlignment(headerStyle.ALIGN_CENTER);
headerStyle.setFont(headerFont);
headerStyle.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
int rowCount= 0;
Row header;
header = sheet.createRow(0);//its for header
Cell cell ;//= header.createCell(0);
for(int j = 0;j < 4; j++) {
cell = header.createCell(j);
if(j == 0) {
cell.setCellValue("ItemWise List");
}
cell.setCellStyle(headerStyle);
}
sheet.addMergedRegion(new CellRangeAddress(rowCount, rowCount, 0, lstReportFormHeader.size()-1));
header = sheet.createRow(0);
cell = header.createCell(0);
cell.setCellValue("Sr. No");
cell = header.createCell(1);
cell.setCellValue("Item Name");
cell = header.createCell(2);
cell.setCellValue("Qty");
cell = header.createCell(3);
cell.setCellValue("Rate");
Now I want to ItemWise List merge and make it align center.
My solution was to merge the cells by their positions, then created a cell (reference to the first block of the merged cells) to assign a value and then set the alignment throught the CellUtil
// Merges the cells
CellRangeAddress cellRangeAddress = new CellRangeAddress(start, start, j, j + 1);
sheet.addMergedRegion(cellRangeAddress);
// Creates the cell
Cell cell = CellUtil.createCell(row, j, entry.getKey());
// Sets the allignment to the created cell
CellUtil.setAlignment(cell, workbook, CellStyle.ALIGN_CENTER);
Merge like:::
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");
Row row = sheet.createRow((short) 1);
Cell cell = row.createCell((short) 1);
cell.setCellValue("This is a test of merging");
sheet.addMergedRegion(new CellRangeAddress(
1, //first row (0-based)
1, //last row (0-based)
1, //first column (0-based)
2 //last column (0-based)
));
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
For aligning also check the below official link of Apache poi:::
http://poi.apache.org/spreadsheet/quick-guide.html#Alignment
After study I found that after merging 7 cells, merged cell id will be 0 so I applied following style to cell id 0 using following style.
headerStyle.setAlignment(headerStyle.ALIGN_CENTER);
This worked for me and I think it's cleaner:
/**
* Merge and center the cells specified by range
* #param startCell the first cell in the cells to be merged
* #param range the range of the cells to be merged
*/
private static void mergeAndCenter(Cell startCell, CellRangeAddress range) {
startCell.getSheet().addMergedRegion(range);
CellStyle style = startCell.getSheet().getWorkbook().createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
startCell.setCellStyle(style);
}
As per my understanding, you have start and end cells for merging and you want to merge the cell ranges and align the cell content. If I am right, you can use the following method:
/**
* #param startCell: first cell of merging area
* #param endCell: last cell of merging area
*/
public static void mergeAndAlignCenter(HSSFCell startCell, HSSFCell endCell){
//finding reference of start and end cell; will result like $A$1
CellReference startCellRef= new CellReference(startCell.getRowIndex(),startCell.getColumnIndex());
CellReference endCellRef = new CellReference(endCell.getRowIndex(),endCell.getColumnIndex());
// forming string of references; will result like $A$1:$B$5
String cellRefernce = startCellRef.formatAsString()+":"+endCellRef.formatAsString();
//removing $ to make cellRefernce like A1:B5
cellRefernce = cellRefernce.replace("$","");
//passing cellRefernce to make a region
CellRangeAddress region = CellRangeAddress.valueOf(cellRefernce);
//use region to merge; though other method like sheet.addMergedRegion(new CellRangeAddress(1,1,4,1));
// is also available, but facing some problem right now.
startCell.getRow().getSheet().addMergedRegion( region );
//setting alignment to center
CellUtil.setAlignment(startCell, wb, CellStyle.ALIGN_CENTER);
}
Well what worked for me is to set all the merged cells' Cellstyle to CENTER ALIGN. Whether you put the XSSFSheet.addMergedRegion() method before or after setting the cellstyle values to center don't matter.
private void insertXlsHeader(XSSFSheet sheet){
....
//first cell for row1
cell = row1.createCell(colstart);
cell.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING);
cell.setCellValue("COURSES");
setHeaderCellStyle(sheet,cell);
//first cell for row2
cell = row2.createCell(colstart);
setHeaderCellStyle(sheet,cell);
//first cell for row3
cell = row3.createCell(colstart);
setHeaderCellStyle(sheet,cell);
//merged the first cells of rows 1 to 3
sheet.addMergedRegion(new CellRangeAddress(ROW1, ROW3, colstart, colstart));
...
}
private void setHeaderCellStyle(XSSFSheet sheet,org.apache.poi.ss.usermodel.Cell cell) {
CellStyle s = null;
s = sheet.getWorkbook().createCellStyle();
cell.setCellStyle(s);
Font f = sheet.getWorkbook().createFont();
f.setBoldweight(Font.BOLDWEIGHT_BOLD);
s.setBorderBottom(CellStyle.BORDER_THIN);
s.setBorderLeft(CellStyle.BORDER_THIN);
s.setBorderRight(CellStyle.BORDER_THIN);
s.setBorderTop(CellStyle.BORDER_THIN);
s.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
s.setAlignment(CellStyle.ALIGN_CENTER);
s.setFont(f);
}
As answered above, merging cells can be achieved using
sheet.addMergedRegion(new CellRangeAddress(frstRow, lastRow, firstColumnIndex, lastColumnIndex));
But for aligning cells vertically,recently I faced similar issue and I tried above answer, but using
CellUtil.setAlignment(dataCell, workbook, CellStyle.VERTICAL_CENTER);
aligned Date formatted cells to Horizontal Left aligned. So I used following method to set only Vertical Alignment of Cell content.
CellUtil.setCellStyleProperty(dataCell, workbook,CellUtil.VERTICAL_ALIGNMENT,CellStyle.VERTICAL_CENTER);
I hope this helps!!
Happy Coding
Use
style.setVerticalAlignment()
to set the vertical alignments instead of
style.setAlignment().
We can merge the column along with we can vertically and horizontally align too.
I had the rows 2 to 10 of column A having the same values.
I used the below code to merge the data where the variable sheet is XSSFSheet. The parameters of CellRangeAddress have the parameters are start row, last row, start column and last column. In my example, the value USA starts from 2nd row (index is 1) and the last value of USA is in 10th row and column is the 1st column.
CellRangeAddress ca = new CellRangeAddress(1,9,0,0);
sheet.addMergedRegion(ca);
When I executed the above code, the cell was merged but the text was not aligned to center.
To overcome this issue, I utilized the class CellStyle and Cell. Get the 2nd row of 1st column text to cell variable. Now set the vertical and horizontal alignment to the cellStyle and set this style to the cell which will align the text to the center.
Cell cell = sheet.getRow(1).getCell(0);
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cell.setCellStyle(cellStyle);
Below is the final result
Additional references :
Jar files used
Import statements

Auto size height for rows in Apache POI

I am inputting values into a spreadsheet using Apache POI. These values have newlines, and I was able to use this code successfully:
CellStyle style = cell.getCellStyle()
style.setWrapText(true)
cell.setCellStyle(style)
Unfortunately, while the text is wrapping correctly, the rows are not always growing in height enough to show the content. How do I ensure that my rows are always the correct height?
currentRow.setHeight((short)-1)
Works for XSSFCell and Excel 2013
HSSFWorkbook workbook=new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("FirstSheet");
HSSFRow rowhead= sheet.createRow((short)0);
HSSFCellStyle style = workbook.createCellStyle();
style.setWrapText(true);
row.setRowStyle(style);
row.getCell(0).setCellStyle(style);
The above code will generate dynamic height of rows.
The only way I got this to work was write my own implementation to calculate the row height. The code is now released as the Taro project, so you could use that. It has numerous convenience methods to let you write an Excel file in far fewer lines of code.
If you prefer to put the implementation in your own code, you can find it in the SpreadsheetTab class. There is an autoSizeRow(int rowIndex) method half way down. It basically iterates down the row and for each cell finds the number of lines of text, then uses the font size to calculate the optimal cell height. It then sets the row height to the height of the tallest cell.
See all this link, which provides some code to manually calculate the correct height for a row, based on the column width and cell content. I've not personally tested it. Also pasted below for convenience:
// Create Font object with Font attribute (e.g. Font family, Font size, etc) for calculation
java.awt.Font currFont = new java.awt.Font(fontName, 0, fontSize);
AttributedString attrStr = new AttributedString(cellValue);
attrStr.addAttribute(TextAttribute.FONT, currFont);
// Use LineBreakMeasurer to count number of lines needed for the text
FontRenderContext frc = new FontRenderContext(null, true, true);
LineBreakMeasurer measurer = new LineBreakMeasurer(attrStr.getIterator(), frc);
int nextPos = 0;
int lineCnt = 0;
while (measurer.getPosition() < cellValue.length())
{
nextPos = measurer.nextOffset(mergedCellWidth); // mergedCellWidth is the max width of each line
lineCnt++;
measurer.setPosition(nextPos);
}
Row currRow = currSht.getRow(rowNum);
currRow.setHeight((short)(currRow.getHeight() * lineCnt));
// The above solution doesn't handle the newline character, i.e. "\n", and only
// tested under horizontal merged cells.
cell.getRow().setHeight((short) -1);
Worked for HSSFCell in apache poi 3.9 or above
It works in Excel 2010.
I set the limit of cell length of 50 characters
Row row = sheet.createRow(0);
CellStyle style = workbook.createCellStyle();
style.setWrapText(true);
if (data.length() > 50) {
for (int i = 1; i <= Math.abs(data.length() / 50); i++) {
data = data.substring(0, i * 50) + "\n" + data.substring(i * 50);
}
Cell cell = row.createCell(0);
row.setRowStyle(style);
cell.setCellStyle(style);
cell.setCellValue(data);
sheet.autoSizeColumn(0);
}
In my case a robust solution was to calculate the number of lines and set the row height to a multiple of the default row height:
int numberOfLines = cell.getStringCellValue().split("\n").length;
row.setHeightInPoints(numberOfLines*sheet.getDefaultRowHeightInPoints());
You can't adjust cell height directly.
But you can change the row's height
final HSSFSheet fs = wb.createSheet("sheet1");
final HSSFRow row0 = fs.createRow(0);
final HSSFCell cellA1 = row0.createCell(0);
row0.setHeight((short)700);
Row aitosize work for me:
cell.getRow().setHeight((short)0);
Here 0 for calculate autoheight.
Workaround for “LibreOffice Calc“ and “WPS Spreadsheet” with auto height for merged sells.
I add a column out to the right of a main document (In my case it was 32 column)
Set width as all merged cells with same text.
Set style WrapText to true
Set style to Align Top
Copy content which will be displayed in the merged cells
Set that column to be hidden
Set a row height = -1
A sample of code:
private void applyRowHightWorkaroundForMergedCells(HSSFCell cell0) {
HSSFSheet sheet = cell0.getSheet();
HSSFRow row = cell0.getRow();
String value = cell0.getStringCellValue();
HSSFCell cell = row.createCell(32);
sheet.setColumnWidth(32, 32000);
cell.getCellStyle().setWrapText(true);
cell.getCellStyle().setVerticalAlignment(VerticalAlignment.TOP);
cell.setCellValue(value);
sheet.setColumnHidden(32, true);
row.setHeight((short) -1);
}
//we can use column width for sheet
Ex: sheet.setColumnWidth(0, 2000);

creating cell comments using HSSFClientAnchor in apache poi

Could someone please explain to me how to properly use the Anchors when creating cell comments? Mine were working, but the spread sheet changed and I am having issues getting my cell comments to appear. This is the code I was using that worked:
Comment c = drawing.createCellComment (new HSSFClientAnchor(0, 0, 0, 0, (short)4, 2, (short)6, 5));
That was found mostly by experimenting around. Looking at the api for it doesn't exactly make it any clearer.
Based on the quick start guide I have also tried the following with no luck:
ClientAnchor anchor = chf.createClientAnchor();
Comment c = drawing.createCellComment(anchor);
c.setString(chf.createRichTextString(message));
A bit late, but this will probably work (it works for me, while the Apache POI example from the quick start also didn't work for me):
public void setComment(String text, Cell cell) {
final Map<Sheet, HSSFPatriarch> drawingPatriarches = new HashMap<Sheet, HSSFPatriarch>();
CreationHelper createHelper = cell.getSheet().getWorkbook().getCreationHelper();
HSSFSheet sheet = (HSSFSheet) cell.getSheet();
HSSFPatriarch drawingPatriarch = drawingPatriarches.get(sheet);
if (drawingPatriarch == null) {
drawingPatriarch = sheet.createDrawingPatriarch();
drawingPatriarches.put(sheet, drawingPatriarch);
}
Comment comment = drawingPatriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));
comment.setString(createHelper.createRichTextString(text));
cell.setCellComment(comment);
}
Erik Pragt
The following code works for me for Office 2007 (xlsx) format files. Figured this out from POI guide
http://poi.apache.org/spreadsheet/quick-guide.html#CellComments
and
How to set comments for 3 cells using apache poi
protected void setCellComment(Cell cell, String message) {
Drawing drawing = cell.getSheet().createDrawingPatriarch();
CreationHelper factory = cell.getSheet().getWorkbook()
.getCreationHelper();
// When the comment box is visible, have it show in a 1x3 space
ClientAnchor anchor = factory.createClientAnchor();
anchor.setCol1(cell.getColumnIndex());
anchor.setCol2(cell.getColumnIndex() + 1);
anchor.setRow1(cell.getRowIndex());
anchor.setRow2(cell.getRowIndex() + 1);
anchor.setDx1(100);
anchor.setDx2(100);
anchor.setDy1(100);
anchor.setDy2(100);
// Create the comment and set the text+author
Comment comment = drawing.createCellComment(anchor);
RichTextString str = factory.createRichTextString(message);
comment.setString(str);
comment.setAuthor("Apache POI");
// Assign the comment to the cell
cell.setCellComment(comment);
}

Categories