Commit 850b489b authored by yanzg's avatar yanzg

导出Excel边框

parent 6590f3cf
......@@ -18,10 +18,6 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
......@@ -60,7 +56,7 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
/**
* 单元格央视
*/
private CellStyle style;
private CellStyle defaultStyle;
/**
* 行号
......@@ -76,16 +72,6 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
*/
private int cacheRow = 1000;
/**
* 合并列表組
*/
private Map<String, List<String>> mergerGroup;
/**
* 是否需要合并单元格
*/
private Map<String, ExcelMergerData> mergerGroupData;
/**
* 控制台输出Excel
*
......@@ -141,9 +127,9 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
* @return 当前处理行
*/
public ExcelRow<T> getRowHandle() {
ExcelRow rowHandle;
ExcelRow<T> rowHandle;
if (this.rowHandle == null) {
rowHandle = ExcelRowDefault.getInstance();
rowHandle = new ExcelRowDefault<>();
} else {
rowHandle = this.rowHandle;
}
......@@ -164,9 +150,18 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
* 检测参数是否异常
*/
public ExcelConsole<T> check() {
CheckerHelper check = CheckerHelper.newInstance().notBlankCheck("导出xls配置", this.config).notBlankCheck("导出xls.标题", this.config.getTitle()).notBlankCheck("导出xls.子标题", this.config.getSubTitle()).notBlankCheck("导出xls.服务器路径", this.config.getServerPath()).notBlankCheck("导出xls.文件名", this.config.getFileName()).notBlankListCheck("导出xls.列", this.config.getColumns()).checkException();
CheckerHelper check = CheckerHelper.newInstance()
.notBlankCheck("导出xls配置", this.config)
.notBlankCheck("导出xls.标题", this.config.getTitle())
.notBlankCheck("导出xls.子标题", this.config.getSubTitle())
.notBlankCheck("导出xls.服务器路径", this.config.getServerPath())
.notBlankCheck("导出xls.文件名", this.config.getFileName())
.notBlankListCheck("导出xls.列", this.config.getColumns())
.checkException();
for (ExportColumn column : this.config.getColumns()) {
check.notBlankCheck("导出xls.列名", column.getName()).notBlankCheck("导出xls.标题", column.getTitle()).checkException();
check.notBlankCheck("导出xls.列名", column.getName())
.notBlankCheck("导出xls.标题", column.getTitle())
.checkException();
}
return this;
......@@ -196,9 +191,6 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
if (this.workbook != null) {
throw YzgError.getRuntimeException("034");
}
// 创建合并对象数据检测
mergerGroup = new HashMap<>(20);
mergerGroupData = new HashMap<>(20);
if (this.cacheRow < 1) {
this.cacheRow = 1000;
......@@ -208,8 +200,8 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
workbook = new SXSSFWorkbook(this.cacheRow);
workbook.setCompressTempFiles(true);
sheet = workbook.createSheet();
style = initColumnCenterStyle(workbook);
// 默认央视
defaultStyle = initColumnCenterStyle(workbook);
// 行和列都是从0开始计数,且起始结束都会合并
......@@ -235,7 +227,7 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
// 创建一行
Row row = sheet.createRow(rowIndex);
row.setHeight(getUnit(rowHeight));
createCell(row, 0, content);
createCell(row, 0, content, defaultStyle);
// 这里是合并excel中多列为1列
CellRangeAddress region = new CellRangeAddress(rowIndex, rowIndex, 0, columnLength);
sheet.addMergedRegion(region);
......@@ -257,7 +249,7 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
// 写入列头
for (TableHeadItem headItem : head.getColumns()) {
Row row = rows[headItem.getRow()];
createCell(row, headItem.getColumn(), headItem.getName());
createCell(row, headItem.getColumn(), headItem.getName(), defaultStyle);
// 判断是否需要合并列头
if (headItem.getColumnCell() > 1 || headItem.getRowCell() > 1) {
......@@ -271,27 +263,15 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
}
}
// 合并数据配置
for (ExportColumn column : this.config.getColumns()) {
if (!column.isMerger()) {
continue;
}
// 获取需要合并的組,不能为null
String group = StringHelper.getFirst(column.getMegerGroup());
column.setMegerGroup(group);
if (!mergerGroup.containsKey(group)) {
mergerGroup.put(group, new ArrayList<>());
mergerGroupData.put(group, new ExcelMergerData());
}
// 当前合并組中添加需要合并的列
mergerGroup.get(group).add(column.getName());
}
// 设置列宽度
int columnPos = 0;
// 合并数据配置
for (ExportColumn column : this.config.getColumns()) {
sheet.setColumnWidth(columnPos, getUnit(column.getWidth()));
columnPos++;
// 列样式
column.cellStyle = createColumnStyle(this.workbook, column);
}
}
......@@ -320,40 +300,32 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
Row row = sheet.createRow(rowIndex);
// 高度
int height = getUnit(this.config.getRowHeight());
// 合并組数据处理
for (Map.Entry<String, List<String>> groupKvp : mergerGroup.entrySet()) {
// 将当前組生成值密钥
StringBuilder sb = new StringBuilder();
for (String columnName : groupKvp.getValue()) {
String value = StringHelper.getFirst(rowHandle.get(t, columnName));
sb.append(value.replace(":", "::"));
sb.append(":");
}
String groupValue = StringHelper.md5(sb.toString());
// 更新合并内容
ExcelMergerData mergerData = mergerGroupData.get(groupKvp.getKey());
mergerData.updateMerger(rowIndex, groupValue);
}
// 将当前組生成值密钥
StringBuilder sb = new StringBuilder();
// 写入本行内容
int columnPos = 0;
for (ExportColumn column : this.config.getColumns()) {
String columnName = column.getName();
String value = StringHelper.getFirst(rowHandle.get(t, columnName));
// 合并組数据处理
if (column.isMerger()) {
sb.append(value.replace(":", "::"));
sb.append(":");
String groupValue = StringHelper.md5(sb.toString());
// 更新合并内容
column.groupData.updateMerger(rowIndex, groupValue);
}
// 单元格总宽度
int cellWidth = getTextChineseLength(value) * 256;
// 列宽度
int columnWidth = getUnit(column.getWidth() - 10);
// 中文长度
int chinese = this.chinese.matcher(value).groupCount();
// 实际内容宽度
int wordLength = value.length() + chinese;
int cellWidth = wordLength * 256;
// 当前单元格实际行高
int nowCellHeight = StringHelper.getPage(cellWidth, columnWidth) * getUnit(this.config.getRowHeight());
// 当前行行高
height = Math.max(nowCellHeight, height);
// 当不需要合并历史记录时,则创建新的内容
createCell(row, columnPos, value);
createCell(row, columnPos, value, column.cellStyle);
// 合并列
mergerColumn(column, columnPos, false);
columnPos++;
}
......@@ -368,6 +340,19 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
}
}
/**
* 获取文本中文长度
*
* @param value 文本字符串
* @return 内容
*/
private int getTextChineseLength(String value) {
// 中文长度
int chinese = this.chinese.matcher(value).groupCount();
// 实际内容宽度
return value.length() + chinese;
}
/**
* 合并列
*
......@@ -378,11 +363,11 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
private void mergerColumn(ExportColumn column, int columnPos, boolean last) {
// 判断列是否需要合并
if (column.isMerger()) {
ExcelMergerData mergerData = mergerGroupData.get(column.getMegerGroup());
ExcelMergerData mergerData = column.groupData;
// 判断是否需要合并历史记录
if (mergerData.isMergerFlag() || last) {
// 合并历史记录单元格
mergerData(mergerData, columnPos, last);
mergerData(column, mergerData, columnPos, last);
}
}
}
......@@ -390,11 +375,12 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
/**
* 合并数据
*
* @param column 需要合并的列
* @param mergerColumn 需要合并的列
* @param columnPos 合并的列位置
* @param last 是否最后一行,最后一行,则合并之前的数据
*/
private void mergerData(ExcelMergerData mergerColumn, int columnPos, boolean last) {
private void mergerData(ExportColumn column, ExcelMergerData mergerColumn, int columnPos, boolean last) {
int rowStart = mergerColumn.getRowIndexHistory();
int rowEnd = rowStart + mergerColumn.getRowCellHistory() - 1;
if (last) {
......@@ -404,7 +390,7 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
CellRangeAddress region = new CellRangeAddress(rowStart, rowEnd, columnPos, columnPos);
sheet.addMergedRegion(region);
setStyle(region);
setDefaultStyle(region, column.cellStyle);
}
/**
......@@ -492,16 +478,17 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
/**
* 创建单元格
*
* @param row 行
* @param column 列
* @param content 内容
* @param row 行
* @param column 列
* @param content 内容
* @param cellStyle 设置默认样式
* @return 单元格
*/
private Cell createCell(Row row, int column, String content) {
private Cell createCell(Row row, int column, String content, CellStyle cellStyle) {
// 获取字节数、用于设置最大宽度
Cell cell = row.createCell(column);
cell.setCellStyle(style);
cell.setCellValue(content);
cell.setCellStyle(cellStyle);
return cell;
}
......@@ -513,17 +500,22 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
* <b>@return</b>
*/
public CellStyle initColumnCenterStyle(Workbook wb) {
return createStyle(wb, true);
}
private CellStyle createStyle(Workbook wb, boolean isDefault) {
CellStyle cellStyle = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 10);
cellStyle.setFont(font);
// 左右居中
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
// 上下居中
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
if (isDefault) {
// 左右居中
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
// 上下居中
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
}
// 设置自动换行
cellStyle.setWrapText(true);
// 设置单元格的边框颜色.
......@@ -538,19 +530,52 @@ public class ExcelConsole<T extends Object> implements DbRow<T> {
cellStyle.setBorderBottom(CellStyle.BORDER_THIN);
// 设置单元格的背景颜色.
cellStyle.setFillForegroundColor(HSSFColor.WHITE.index);
return cellStyle;
}
private void setStyle(CellRangeAddress region) {
private CellStyle createColumnStyle(SXSSFWorkbook wb, ExportColumn column) {
CellStyle style = this.createStyle(wb, false);
// 左右居中
switch (column.getAlignment()) {
case 1:
style.setAlignment(CellStyle.ALIGN_LEFT);
break;
case 2:
style.setAlignment(CellStyle.ALIGN_RIGHT);
break;
case 0:
default:
style.setAlignment(CellStyle.ALIGN_CENTER);
break;
}
// 上下居中
switch (column.getVerticalAlignment()) {
case 1:
style.setVerticalAlignment(CellStyle.VERTICAL_TOP);
break;
case 2:
style.setVerticalAlignment(CellStyle.VERTICAL_BOTTOM);
break;
case 0:
default:
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
break;
}
return style;
}
private void setDefaultStyle(CellRangeAddress region, CellStyle cellStyle) {
// 使用RegionUtil类为合并后的单元格添加边框
RegionUtil.setBorderTop(style.getBorderTop(), region, sheet, this.workbook);
RegionUtil.setBorderLeft(style.getBorderLeft(), region, sheet, this.workbook);
RegionUtil.setBorderRight(style.getBorderRight(), region, sheet, this.workbook);
RegionUtil.setBorderBottom(style.getBorderBottom(), region, sheet, this.workbook);
RegionUtil.setTopBorderColor(style.getTopBorderColor(), region, sheet, this.workbook);
RegionUtil.setLeftBorderColor(style.getLeftBorderColor(), region, sheet, this.workbook);
RegionUtil.setRightBorderColor(style.getRightBorderColor(), region, sheet, this.workbook);
RegionUtil.setBottomBorderColor(style.getBottomBorderColor(), region, sheet, this.workbook);
RegionUtil.setBorderTop(cellStyle.getBorderTop(), region, sheet, this.workbook);
RegionUtil.setBorderLeft(cellStyle.getBorderLeft(), region, sheet, this.workbook);
RegionUtil.setBorderRight(cellStyle.getBorderRight(), region, sheet, this.workbook);
RegionUtil.setBorderBottom(cellStyle.getBorderBottom(), region, sheet, this.workbook);
RegionUtil.setTopBorderColor(cellStyle.getTopBorderColor(), region, sheet, this.workbook);
RegionUtil.setLeftBorderColor(cellStyle.getLeftBorderColor(), region, sheet, this.workbook);
RegionUtil.setRightBorderColor(cellStyle.getRightBorderColor(), region, sheet, this.workbook);
RegionUtil.setBottomBorderColor(cellStyle.getBottomBorderColor(), region, sheet, this.workbook);
}
}
package com.yanzuoguang.excel;
import io.swagger.annotations.ApiModelProperty;
/**
* 单元格
*
* @author 颜佐光
*/
public class ExcelDefineCell {
/**
* 横合并
*/
@ApiModelProperty(notes = "横合并")
private short widthSize;
/**
* 竖合并
*/
@ApiModelProperty(notes = "竖合并")
private short heightSize;
/**
* 对其
*/
@ApiModelProperty(notes = "左右对其:0-居中,1-左对其,2-右对齐")
private int alignment;
/**
* 对其
*/
@ApiModelProperty(notes = "上下对其:0-居中,1-上对其,2-下对齐")
private int verticalAlignment;
/**
* 文字内容
*/
@ApiModelProperty(notes = "文字内容")
private String value;
/**
* 公式,如:SUM(C2:C3),或者SUM(columnName),columnName=数据列名称,公式优先
*/
@ApiModelProperty(notes = " 公式,如:SUM(C2:C3),或者SUM(columnName),columnName=数据列名称,公式优先.不能SUM(columnA/columnB)")
private String formula;
public short getWidthSize() {
return widthSize;
}
public void setWidthSize(short widthSize) {
this.widthSize = widthSize;
}
public short getHeightSize() {
return heightSize;
}
public void setHeightSize(short heightSize) {
this.heightSize = heightSize;
}
public int getAlignment() {
return alignment;
}
public void setAlignment(int alignment) {
this.alignment = alignment;
}
public int getVerticalAlignment() {
return verticalAlignment;
}
public void setVerticalAlignment(int verticalAlignment) {
this.verticalAlignment = verticalAlignment;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getFormula() {
return formula;
}
public void setFormula(String formula) {
this.formula = formula;
}
}
package com.yanzuoguang.excel;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;
import java.util.List;
/**
* 单元格
*
* @author 颜佐光
*/
public class ExcelDefineRow {
/**
* 高度
*/
@ApiModelProperty(notes = "高度")
private short height;
/**
* 单元格
*/
@ApiModelProperty(notes = "单元格")
private List<ExcelDefineCell> cells = new ArrayList<>();
public short getHeight() {
return height;
}
public void setHeight(short height) {
this.height = height;
}
public List<ExcelDefineCell> getCells() {
return cells;
}
public void setCells(List<ExcelDefineCell> cells) {
this.cells = cells;
}
}
......@@ -7,7 +7,7 @@ import com.yanzuoguang.util.base.ObjectHelper;
* 行数据默认处理
* @author 颜佐光
*/
public class ExcelRowDefault implements ExcelRow<Object> {
public class ExcelRowDefault<T> implements ExcelRow<T> {
/**
* 获取行里面的某列数据
......@@ -17,18 +17,7 @@ public class ExcelRowDefault implements ExcelRow<Object> {
* @return
*/
@Override
public String get(Object row, String field) {
public String get(T row, String field) {
return ObjectHelper.getString(row, field);
}
private static final ExcelRowDefault my = new ExcelRowDefault();
/**
* 获取默认实例
*
* @return
*/
public static ExcelRowDefault getInstance() {
return my;
}
}
......@@ -2,6 +2,7 @@ package com.yanzuoguang.excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.apache.poi.ss.usermodel.CellStyle;
/**
* 列设置
......@@ -18,7 +19,7 @@ public class ExportColumn {
private String title;
/**
* 数据单元格
* 数据列名称
*/
@ApiModelProperty(notes = "数据列名称")
private String name;
......@@ -28,18 +29,25 @@ public class ExportColumn {
*/
@ApiModelProperty(notes = "数据是否合并")
private boolean merger;
/**
* 合并組
*/
@ApiModelProperty(notes = "合并組")
private String megerGroup;
/**
* 宽度
*/
@ApiModelProperty(notes = "宽度")
private short width;
/**
* 对其
*/
@ApiModelProperty(notes = "左右对其:0-居中,1-左对其,2-右对齐")
private int alignment;
/**
* 对其
*/
@ApiModelProperty(notes = "上下对其:0-居中,1-上对其,2-下对齐")
private int verticalAlignment;
ExcelMergerData groupData = new ExcelMergerData();
CellStyle cellStyle;
public ExportColumn() {
}
......@@ -55,11 +63,10 @@ public class ExportColumn {
this.width = width;
}
public ExportColumn(String title, String name, boolean merger, String megerGroup, short width) {
public ExportColumn(String title, String name, boolean merger, short width) {
this.title = title;
this.name = name;
this.merger = merger;
this.megerGroup = megerGroup;
this.width = width;
}
......@@ -87,14 +94,6 @@ public class ExportColumn {
this.merger = merger;
}
public String getMegerGroup() {
return megerGroup;
}
public void setMegerGroup(String megerGroup) {
this.megerGroup = megerGroup;
}
public short getWidth() {
if (this.width < 1) {
return ExportData.COLUMN_WIDTH;
......@@ -105,4 +104,20 @@ public class ExportColumn {
public void setWidth(short width) {
this.width = width;
}
public int getAlignment() {
return alignment;
}
public void setAlignment(int alignment) {
this.alignment = alignment;
}
public int getVerticalAlignment() {
return verticalAlignment;
}
public void setVerticalAlignment(int verticalAlignment) {
this.verticalAlignment = verticalAlignment;
}
}
......@@ -97,11 +97,21 @@ public class ExportData {
@ApiModelProperty(notes = "自动换行")
private boolean line;
/**
* 数据开始自定义行
*/
@ApiModelProperty(notes = "数据开始自定义行")
private List<ExcelDefineRow> startRows = new ArrayList<>();
/**
* 包含列
*/
@ApiModelProperty(notes = "包含列")
private List<ExportColumn> columns = new ArrayList<>();
/**
* 数据结束自定义行
*/
@ApiModelProperty(notes = "数据结束自定义行")
private List<ExcelDefineRow> endRows = new ArrayList<>();
public String getServerPath() {
return serverPath;
......@@ -195,6 +205,14 @@ public class ExportData {
this.line = line;
}
public List<ExcelDefineRow> getStartRows() {
return startRows;
}
public void setStartRows(List<ExcelDefineRow> startRows) {
this.startRows = startRows;
}
public List<ExportColumn> getColumns() {
return columns;
}
......@@ -202,4 +220,12 @@ public class ExportData {
public void setColumns(List<ExportColumn> columns) {
this.columns = columns;
}
public List<ExcelDefineRow> getEndRows() {
return endRows;
}
public void setEndRows(List<ExcelDefineRow> endRows) {
this.endRows = endRows;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment