如何使用 Apache POI 4.0.1 和 java 在整个数据的每一侧留下一个单元格 space 来设置边框
How to set border by leaving one cell space along each side of entire data using Apache POI 4.0.1 and java
- 目前,我可以在整个数据旁边设置边框(您可以参考下图)。
Current output
Code snippet
// Code to draw Border at left side
int rowstart = 3, rowend = 9;
int col = 2;
for (rowstart = 1; rowstart <= rowend; rowstart++) {
Row rowL = sheet.createRow(rowstart);
Cell cell = rowL.createCell(col);
{
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderLeft(BorderStyle.MEDIUM);
cell.setCellStyle(style);
}
}
// Code to draw Border at bottom
int colstart1 = 2, colend1 = 6;
Row rowB = sheet.createRow(90);
for (colstart1 = 2; colstart1 <= colend1; colstart1++) {
Cell cellB = rowB.createCell(colstart1);
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderTop(BorderStyle.MEDIUM);
cellB.setCellStyle(style);
}
// Code to draw Border at top
int colstart = 2, colend = 6;
Row rowT = sheet.createRow(0);
for (colstart = 2; colstart <= colend; colstart++) {
Cell cell = rowT.createCell(colstart);
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderBottom(BorderStyle.MEDIUM);
cell.setCellStyle(style);
}
// Code to draw Border at Right side
int rowstart1 = 1, rowend1 = 9;
for (rowstart1 = 1; rowstart1 <= rowend1; rowstart1++) {
Row rowR = sheet.getRow(rowstart1);
Cell cellR = rowR.createCell(20);
{
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderRight(BorderStyle.MEDIUM);
cellR.setCellStyle(style);
}
}
- 我想在整个数据旁边设置边框,但是在数据和边框之间留一个单元格 space(您可以参考下图)。
Expected output
不要用那么复杂的方式绘制边框。
如果要这样做(使用单个 CellStyle
s),则需要创建 8 个单单元格样式。一种具有左上边缘的边框,一种具有顶线的边框,一种具有右上边缘的边框,一种具有左线的边框,一种具有右线的边框,一种具有左下边缘的边框,一种具有底线和一个右下角有边框的线。然后,在创建单元格并用内容填充它们之后,必须将正确的单元格样式(之前创建的 8 个中的一个)应用于单元格。
编码起来既丑陋又复杂。所以人们经常做你所做的,只是为每个单元格创建一个新的单元格样式。但是 Excel
的唯一单元格 formats/cell 样式数量有限。参见 Excel specifications and limits。因此,拥有大量数据的大 sheet 很容易超过 64,000 个独特单元格 formats/cell 样式的限制。所以简单地为每个单元格创建一个新的单元格样式是错误的。
Drawing Borders in Busy Developers' Guide to HSSF and XSSF Features 展示了如何做得更好。
完整示例:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.PropertyTemplate;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class ExcelDrawingBorders {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("ExcelDrawingBorders.xlsx") ) {
int startDataRow = 4;
int endDataRow = 8;
int startDataColumn = 2;
int endDataColumn = 6;
Sheet sheet = workbook.createSheet();
for (int r = startDataRow; r <= endDataRow; r++) {
Row row = sheet.createRow(r);
for (int c = startDataColumn; c <= endDataColumn; c++) {
Cell cell = row.createCell(c);
cell.setCellFormula("RANDBETWEEN(10,50)");
}
}
PropertyTemplate propertyTemplate = new PropertyTemplate();
propertyTemplate.drawBorders(new CellRangeAddress(startDataRow-1, endDataRow+1, startDataColumn-1, endDataColumn+1),
BorderStyle.MEDIUM, BorderExtent.OUTSIDE);
propertyTemplate.applyBorders(sheet);
workbook.write(fileout);
}
}
}
结果:
这里 PropertyTemplate and CellUtil 会为您完成所有工作。 PropertyTemplate
创建所需的属性 Map
。在应用于 sheet 时,它使用 CellUtil
在工作簿级别创建 8 个所需的单元格样式并将它们应用于正确的单元格。即使不存在但需要的单元格也会被创建。
Code Sample
PropertyTemplate ptT = new PropertyTemplate();
ptT.drawBorders(new CellRangeAddress(3, 3, 2, 6),
BorderStyle.THICK, BorderExtent.TOP);
ptT.applyBorders(sheet);
PropertyTemplate ptL = new PropertyTemplate();
ptL.drawBorders(new CellRangeAddress(3, 9, 2, 2),
BorderStyle.THICK, BorderExtent.LEFT);
ptL.applyBorders(sheet);
PropertyTemplate ptR = new PropertyTemplate();
ptR.drawBorders(new CellRangeAddress(3, 9, 6, 6),
BorderStyle.THICK, BorderExtent.RIGHT);
ptR.applyBorders(sheet);
PropertyTemplate ptB = new PropertyTemplate();
ptB.drawBorders(new CellRangeAddress(9, 9, 2, 6),
BorderStyle.THICK, BorderExtent.BOTTOM);
ptB.applyBorders(sheet);
- 目前,我可以在整个数据旁边设置边框(您可以参考下图)。
Current output
Code snippet
// Code to draw Border at left side
int rowstart = 3, rowend = 9;
int col = 2;
for (rowstart = 1; rowstart <= rowend; rowstart++) {
Row rowL = sheet.createRow(rowstart);
Cell cell = rowL.createCell(col);
{
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderLeft(BorderStyle.MEDIUM);
cell.setCellStyle(style);
}
}
// Code to draw Border at bottom
int colstart1 = 2, colend1 = 6;
Row rowB = sheet.createRow(90);
for (colstart1 = 2; colstart1 <= colend1; colstart1++) {
Cell cellB = rowB.createCell(colstart1);
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderTop(BorderStyle.MEDIUM);
cellB.setCellStyle(style);
}
// Code to draw Border at top
int colstart = 2, colend = 6;
Row rowT = sheet.createRow(0);
for (colstart = 2; colstart <= colend; colstart++) {
Cell cell = rowT.createCell(colstart);
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderBottom(BorderStyle.MEDIUM);
cell.setCellStyle(style);
}
// Code to draw Border at Right side
int rowstart1 = 1, rowend1 = 9;
for (rowstart1 = 1; rowstart1 <= rowend1; rowstart1++) {
Row rowR = sheet.getRow(rowstart1);
Cell cellR = rowR.createCell(20);
{
XSSFCellStyle style = workbook.createCellStyle();
style.setBorderRight(BorderStyle.MEDIUM);
cellR.setCellStyle(style);
}
}
- 我想在整个数据旁边设置边框,但是在数据和边框之间留一个单元格 space(您可以参考下图)。
Expected output
不要用那么复杂的方式绘制边框。
如果要这样做(使用单个 CellStyle
s),则需要创建 8 个单单元格样式。一种具有左上边缘的边框,一种具有顶线的边框,一种具有右上边缘的边框,一种具有左线的边框,一种具有右线的边框,一种具有左下边缘的边框,一种具有底线和一个右下角有边框的线。然后,在创建单元格并用内容填充它们之后,必须将正确的单元格样式(之前创建的 8 个中的一个)应用于单元格。
编码起来既丑陋又复杂。所以人们经常做你所做的,只是为每个单元格创建一个新的单元格样式。但是 Excel
的唯一单元格 formats/cell 样式数量有限。参见 Excel specifications and limits。因此,拥有大量数据的大 sheet 很容易超过 64,000 个独特单元格 formats/cell 样式的限制。所以简单地为每个单元格创建一个新的单元格样式是错误的。
Drawing Borders in Busy Developers' Guide to HSSF and XSSF Features 展示了如何做得更好。
完整示例:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.PropertyTemplate;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class ExcelDrawingBorders {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("ExcelDrawingBorders.xlsx") ) {
int startDataRow = 4;
int endDataRow = 8;
int startDataColumn = 2;
int endDataColumn = 6;
Sheet sheet = workbook.createSheet();
for (int r = startDataRow; r <= endDataRow; r++) {
Row row = sheet.createRow(r);
for (int c = startDataColumn; c <= endDataColumn; c++) {
Cell cell = row.createCell(c);
cell.setCellFormula("RANDBETWEEN(10,50)");
}
}
PropertyTemplate propertyTemplate = new PropertyTemplate();
propertyTemplate.drawBorders(new CellRangeAddress(startDataRow-1, endDataRow+1, startDataColumn-1, endDataColumn+1),
BorderStyle.MEDIUM, BorderExtent.OUTSIDE);
propertyTemplate.applyBorders(sheet);
workbook.write(fileout);
}
}
}
结果:
这里 PropertyTemplate and CellUtil 会为您完成所有工作。 PropertyTemplate
创建所需的属性 Map
。在应用于 sheet 时,它使用 CellUtil
在工作簿级别创建 8 个所需的单元格样式并将它们应用于正确的单元格。即使不存在但需要的单元格也会被创建。
Code Sample
PropertyTemplate ptT = new PropertyTemplate();
ptT.drawBorders(new CellRangeAddress(3, 3, 2, 6),
BorderStyle.THICK, BorderExtent.TOP);
ptT.applyBorders(sheet);
PropertyTemplate ptL = new PropertyTemplate();
ptL.drawBorders(new CellRangeAddress(3, 9, 2, 2),
BorderStyle.THICK, BorderExtent.LEFT);
ptL.applyBorders(sheet);
PropertyTemplate ptR = new PropertyTemplate();
ptR.drawBorders(new CellRangeAddress(3, 9, 6, 6),
BorderStyle.THICK, BorderExtent.RIGHT);
ptR.applyBorders(sheet);
PropertyTemplate ptB = new PropertyTemplate();
ptB.drawBorders(new CellRangeAddress(9, 9, 2, 6),
BorderStyle.THICK, BorderExtent.BOTTOM);
ptB.applyBorders(sheet);