poi绘制复杂Excel特殊表头(自测成功)
作者:互联网
开箱即用–页签设置(鼠标悬停)–宽度自适应–多表格–多样式–配置灵活–自测成功
开箱即用–页签设置–宽度自适应–多表格–多样式–配置灵活–自测成功
生成效果:
sheet1:
sheet2:
sheet3:
sheet4:
代码较长,方法互不关联,自行选择部分即可
```java
@RequestMapping("/text")
@ResponseBody
public void userDownData(HttpServletResponse response, @RequestParam(value = "userName", required = false) String userName) throws IOException {
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
HSSFSheet sheet1 = createSheet(hssfWorkbook, "工资总表");
HSSFCellStyle style = hssfWorkbook.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setAlignment(HorizontalAlignment.CENTER); // 左右居中
style.setVerticalAlignment(style.getVerticalAlignmentEnum().CENTER); //上下居中
Font font = hssfWorkbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 24);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
style.setFont(font);
HSSFRow row = setSheetDetails(sheet1.createRow(0), new String[]{"昆山佑威光电 2020年12月份 工资表"}, style); // 创建行数据并绑定样式
margeCell(sheet1, new int[]{0, 0, 0, 26}); // 合并单元格
fileDetails(sheet1, new String[]{"序", "姓名", "部门", "部门", "离职日期", "身份号码", "银行账号", "底薪标准", "补贴标准", "底薪", "全勤", "工作补贴", "日常加班", "双休加班", "国假加班", "生活补贴", "通讯", "补发", "奖惩",
"应发", "社保", "补医保", "食宿", "个人所得税", "借款", "厂服", "实发工资"}, 1, null); // 写入表格内容
HSSFCellStyle complementStyle = hssfWorkbook.createCellStyle(); // 合并单元格后被合并部分单元格样式会缺失
complementStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
complementStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
complementCellStyle(row, complementStyle, new int[]{1, 27}); // 补全样式
/**
* sheet2
*/
HSSFSheet sheet2 = hssfWorkbook.createSheet("工资格式");
HSSFCellStyle style2 = hssfWorkbook.createCellStyle();
style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
style2.setAlignment(HorizontalAlignment.CENTER);
style2.setVerticalAlignment(style2.getVerticalAlignmentEnum().CENTER);
style2.setWrapText(true); // 自动换行
Font font2 = hssfWorkbook.createFont();
font2.setFontName("宋体");
font2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
font2.setFontHeightInPoints((short) 10);
style2.setFont(font2);
margeCell(sheet2, new int[]{0, 1, 0, 0}, new int[]{0, 1, 1, 1}, new int[]{0, 1, 2, 2}, new int[]{0, 1, 3, 3}, new int[]{0, 1, 4, 4}, new int[]{0, 1, 5, 5}, new int[]{0, 1, 6, 6}, new int[]{0, 1, 7, 7}
, new int[]{0, 1, 8, 8}, new int[]{0, 1, 9, 9}, new int[]{0, 1, 10, 10}, new int[]{0, 0, 11, 17}, new int[]{0, 0, 18, 22}, new int[]{0, 0, 23, 28}, new int[]{0, 0, 29, 31}, new int[]{0, 1, 32, 32}, new int[]{0, 1, 33, 33}
, new int[]{0, 1, 34, 34}, new int[]{0, 1, 35, 35}, new int[]{0, 1, 36, 36}, new int[]{0, 1, 37, 37}); // 需要先合并单元格
HSSFRow row2 = fileDetails(sheet2, new String[]{"序号", "姓名", "工号", "部门", "入职日期", "异动日期", "身份证号", "银行卡号", "薪资性值", "应出勤/H", "实际出勤/H", "薪资标准", "福利", "加班费", "扣款", "本月税前应得薪资", "社保", "公积金", "借贷",
"个人所得税", "实发工资"}, 0, new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 23, 29, 32, 33, 34, 35, 36, 37}, style2); // 写入表格内容
complementCellStyle(row2, complementStyle, new int[]{12, 17}, new int[]{19, 22}, new int[]{24, 28}, new int[]{30, 31}); // 补全边框样式
HSSFRow row2_2 = fileDetails(sheet2, new String[]{"基本工资", "职务工资", "技能工资", "保密工资", "全勤", "岗位", "核定工资总额", "全勤", "补上月", "夜班津贴", "通讯", "通告奖励", "平时加班时间", "平时加班费", "双休加班时间", "双休加班费", "国定加班时间", "国定加班费", "请假",
"住宿", "其他扣款"}, 1, new int[]{11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, style2); // 写入表格内容
complementCellStyle(row2_2, complementStyle, new int[]{0, 10}, new int[]{32, 37}); // 补全边框样式
// 补特殊样式--标签
HSSFComment comment = sheet2.createDrawingPatriarch().createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6)); //前四个参数是坐标点,后四个参数是编辑和显示批注时的大小.
//插入批注
comment.setString(new HSSFRichTextString("漏打卡,离职通告,处罚"));
comment.setAuthor("toad");
row2_2.getCell(31).setCellComment(comment);
/**
* sheet3
*/
HSSFSheet sheet3 = hssfWorkbook.createSheet("工资格式整理公式");
HSSFCellStyle orange = hssfWorkbook.createCellStyle();
orange.setBorderRight(HSSFCellStyle.BORDER_THIN);
orange.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
orange.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); //填充单元格
orange.setFillForegroundColor(HSSFColor.ORANGE.index); // 设置颜色前必须填充单元格
orange.setVerticalAlignment(orange.getVerticalAlignmentEnum().CENTER); //上下居中
orange.setAlignment(HorizontalAlignment.CENTER);
orange.setWrapText(true);
orange.setFont(font2); // 宋体 加粗 10
HSSFCellStyle red = hssfWorkbook.createCellStyle();
red.setBorderRight(HSSFCellStyle.BORDER_THIN);
red.setBorderBottom(HSSFCellStyle.BORDER_THIN);
red.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); //填充单元格
red.setFillForegroundColor(HSSFColor.RED.index); // 设置颜色前必须填充单元格
red.setVerticalAlignment(red.getVerticalAlignmentEnum().CENTER); //上下居中
red.setAlignment(HorizontalAlignment.CENTER);
red.setWrapText(true);
red.setFont(font2); // 宋体 加粗 10
HSSFCellStyle yellow = hssfWorkbook.createCellStyle();
yellow.setBorderRight(HSSFCellStyle.BORDER_THIN);
yellow.setBorderBottom(HSSFCellStyle.BORDER_THIN);
yellow.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); //填充单元格
yellow.setFillForegroundColor(HSSFColor.YELLOW.index); // 设置颜色前必须填充单元格
yellow.setVerticalAlignment(yellow.getVerticalAlignmentEnum().CENTER); //上下居中
yellow.setAlignment(HorizontalAlignment.CENTER);
yellow.setWrapText(true);
yellow.setFont(font2); // 宋体 加粗 10
HSSFCellStyle green = hssfWorkbook.createCellStyle();
green.setBorderRight(HSSFCellStyle.BORDER_THIN);
green.setBorderBottom(HSSFCellStyle.BORDER_THIN);
green.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); //填充单元格
green.setFillForegroundColor(HSSFColor.BRIGHT_GREEN.index); // 设置颜色前必须填充单元格z
green.setVerticalAlignment(green.getVerticalAlignmentEnum().CENTER); //上下居中
green.setAlignment(HorizontalAlignment.CENTER);
green.setWrapText(true);
green.setFont(font2); // 宋体 加粗 10
margeCell(sheet3, new int[]{0, 1, 0, 0}, new int[]{0, 1, 1, 1}, new int[]{0, 0, 2, 7}, new int[]{0, 0, 8, 12}, new int[]{0, 0, 13, 18}, new int[]{0, 0, 19, 21}, new int[]{0, 1, 22, 22}, new int[]{0, 1, 23, 23}, new int[]{0, 1, 24, 24}
, new int[]{0, 1, 25, 25}, new int[]{0, 1, 26, 26}, new int[]{0, 1, 27, 27}, new int[]{0, 1, 28, 28}, new int[]{0, 0, 29, 32});
HSSFRow row3 = fileDetails(sheet3, new String[]{"应出勤/H", "实际出勤/H", "薪资标准", "福利", "加班费", "扣款", "本月税前应得薪资", "社保", "公积金", "借款", "个人所得税", "实发工资", "备注", "辅助列"}, 0,
new int[]{0, 1, 2, 8, 13, 19, 22, 23, 24, 25, 26, 27, 28, 29}, yellow, yellow, style2, style2, style2, style2, green, red, red, style2, green, green, style2, green); // 写入表格内容
complementCellStyle(row3, complementStyle, new int[]{3, 7}, new int[]{9, 12}, new int[]{14, 18}, new int[]{20, 21}, new int[]{30, 32}); // 补全边框样式
HSSFRow row3_2 = fileDetails(sheet3, new String[]{"基本工资", "职务工资", "技能工资", "保密工资", "岗位工资", "核定工资总额(可以不填)", "全勤", "补上月", "夜班津贴", "通讯", "通告奖励", "平时加班时间", "平时加班费", "周末加班时间", "周末加班费",
"国定加班时间", "国定加班费", "请假", "住宿", "其他扣扣", "发薪月数", "月份", "扣税金额", "对应税率"}, 1,
new int[]{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 29, 30, 31, 32}, orange, orange, orange, orange, orange, yellow, red, red, red, red, red, red, red,
red, red, red, red, yellow, red, red, green, green, green, green); // 写入表格内容
// 补特殊样式--标签
HSSFComment comment1 = sheet3.createDrawingPatriarch().createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));
comment1.setString(new HSSFRichTextString("漏打卡,离职通告,处罚"));
comment1.setAuthor("toad");
row3_2.getCell(21).setCellComment(comment1);
complementCellStyle(row3_2, complementStyle, new int[]{0, 1}, new int[]{22, 28}); // 补全边框样式
HSSFSheet sheet4 = hssfWorkbook.createSheet("税率表");
Font font4 = hssfWorkbook.createFont();
font4.setFontName("宋体");
font4.setFontHeightInPoints((short) 10);
HSSFCellStyle red_4 = hssfWorkbook.createCellStyle();
red_4.setBorderBottom(HSSFCellStyle.BORDER_THIN);
red_4.setBorderRight(HSSFCellStyle.BORDER_THIN);
red_4.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); //填充单元格
red_4.setFillForegroundColor(HSSFColor.RED.index); // 设置颜色前必须填充单元格
red_4.setVerticalAlignment(red_4.getVerticalAlignmentEnum().CENTER);
red_4.setAlignment(HorizontalAlignment.CENTER);
red_4.setFont(font4);
HSSFCellStyle white = hssfWorkbook.createCellStyle();
white.setBorderBottom(HSSFCellStyle.BORDER_THIN);
white.setBorderRight(HSSFCellStyle.BORDER_THIN);
white.setVerticalAlignment(red_4.getVerticalAlignmentEnum().CENTER);
white.setAlignment(HorizontalAlignment.CENTER);
white.setFont(font4);
fileDetails(sheet4, new String[]{"下限", "上限", "税率", "速算"}, 0, new int[]{0, 1, 2, 3}, white, red_4, white, white); // 写入表格内容
sheet4.protectSheet("123"); // 最后加锁
MenUserEntity menUserEntity = new MenUserEntity();
menUserEntity.setUserId("0");
menUserEntity.setUserName("张三");
MenUserEntity menUserEntity1 = new MenUserEntity();
menUserEntity1.setUserId("1");
menUserEntity1.setUserName("李四");
MenUserEntity menUserEntity2 = new MenUserEntity();
menUserEntity2.setUserId("222222");
menUserEntity2.setUserName("王五王五王五王五王五王五王五");
MenUserEntity menUserEntity3 = new MenUserEntity();
menUserEntity3.setUserId("3");
menUserEntity3.setUserName("王五王五");
List<Object> list = new ArrayList<>();
list.add(menUserEntity);
list.add(menUserEntity1);
list.add(menUserEntity2);
list.add(menUserEntity3);
addCellDetailSelfWidth(sheet1, 2, list, new String[]{"getUserId", "getUserName"});
// 输出Excel文件
OutputStream output = response.getOutputStream();
response.reset();
response.setHeader("Content-disposition",
"attachment; filename=复杂表头.xls"); //filename = 文件名
hssfWorkbook.write(output);
output.close();
}
/**
* 创建Sheet
*
* @return
*/
public static HSSFSheet createSheet(HSSFWorkbook hssfWorkbook, String sheetName) {
return hssfWorkbook.createSheet(sheetName);
}
/**
* 填充表格内容 -- 默认样式(没有样式)
*/
public static HSSFRow setSheetDetails(HSSFRow row, String[] details) {
for (int i = 0; i < details.length; i++) {
row.createCell(i).setCellValue(details[i]);
}
return row;
}
/**
* 填充表格内容 -- 指定样式
*/
public static HSSFRow setSheetDetails(HSSFRow row, String[] details, HSSFCellStyle style) {
for (int i = 0; i < details.length; i++) {
HSSFCell cell = row.createCell(i); // 不能省
cell.setCellValue(details[i]);
cell.setCellStyle(style);
}
return row;
}
/**
* 指定sheet内 动态合并单元格
*
* @param sheet 指定sheet内
* @param indexs 需要合并的单元格下表
*/
public static void margeCell(HSSFSheet sheet, int[]... indexs) {
for (int[] ints : indexs) {
sheet.addMergedRegion(new CellRangeAddress(ints[0], ints[1], ints[2], ints[3]));
}
}
/**
* sheet指定单元格内填充内容--没有样式
*
* @param sheet
* @param details 需要填充的内容
* @param index 第几行
* @param cellIndex 创建单元格下标,非必填可null
*/
public static void fileDetails(HSSFSheet sheet, String[] details, int index, int[] cellIndex) {
HSSFRow row = sheet.createRow(index);
if (cellIndex != null) {
for (int i = 0; i < details.length; i++) {
row.createCell(i).setCellValue(cellIndex[i]);
}
} else {
for (int i = 0; i < details.length; i++) {
row.createCell(i).setCellValue(details[i]);
}
}
}
/**
* sheet指定单元格内填充内容--统一样式
*
* @param sheet
* @param details 需要填充的内容
* @param index 第几行
* @param style 需要绑定的样式
*/
public static HSSFRow fileDetails(HSSFSheet sheet, String[] details, int index, int[] cellIndex, HSSFCellStyle style) {
HSSFRow row = sheet.createRow(index);
if (cellIndex != null) {
for (int i = 0; i < details.length; i++) {
HSSFCell cell = row.createCell(cellIndex[i]);
cell.setCellStyle(style);
cell.setCellValue(details[i]);
}
} else {
for (int i = 0; i < details.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(style);
cell.setCellValue(details[i]);
}
}
return row;
}
/**
* sheet指定单元格内填充内容--指定样式
*
* @param sheet
* @param map 需要填充的内容和需要绑定的样式
* @param index 第几行
* @param index 需要创建的第几个cell
* @param styles 需要绑定的样
*/
public static HSSFRow fileDetails(HSSFSheet sheet, String[] details, int index, int[] cellIndex, HSSFCellStyle... styles) {
HSSFRow row = sheet.createRow(index);
List<HSSFCellStyle> hssfCellStyleList = new ArrayList<>(styles.length);
for (HSSFCellStyle style : styles) {
hssfCellStyleList.add(style);
}
for (int i = 0; i < details.length; i++) {
HSSFCell cell = row.createCell(cellIndex[i]);
cell.setCellValue(details[i]);
cell.setCellStyle(hssfCellStyleList.get(i));
}
return row;
}
/**
* 补全表格样式--统一
*/
public static void complementCellStyle(HSSFRow row, HSSFCellStyle style, int[] startEnd) {
for (int i = startEnd[0]; i <= startEnd[1]; i++) {
row.createCell(i).setCellStyle(style);
}
}
/**
* 补全表格样式--指定
*/
public static HSSFRow complementCellStyle(HSSFRow row, HSSFCellStyle style, int[]... ints) {
for (int[] anInt : ints) {
for (int j = anInt[0]; j <= anInt[1]; j++) {
row.createCell(j).setCellStyle(style);
}
}
return row;
}
/**
* 补全表格样式--指定
* 第一个map的样式是第一个style,第二个map的样式是第二个style
*/
public static HSSFRow complementCellStyle(HSSFRow row, Map<String, Integer[]> map, HSSFCellStyle... style) {
List<HSSFCellStyle> styleList = new ArrayList<>();
for (HSSFCellStyle hssfCellStyle : style) {
styleList.add(hssfCellStyle);
}
for (int i = 0; i < map.size(); i++) {
for (int j = map.get("complementCell")[0]; j < map.get("complementCell")[0]; j++) {
row.createCell(j).setCellStyle(styleList.get(i));
}
}
return row;
}
/**
* 塞入普通数据
*
* @param sheet 指定sheet
* @param index 创建表格起始行
* @param list 数据源--泛型随便填,如果没有则obj
* @param methods 需要显示的数据,顺序安排
* @return 组建结束的sheet
*/
public static HSSFSheet addCellDetail(HSSFSheet sheet, int index, List<Object> list, String[] methods) {
Class clazz = list.get(0).getClass();
for (int i = 0; i < list.size(); i++) {
Object object = list.get(i);
HSSFRow row = sheet.createRow(index); // 创建行
for (int j = 0; j < methods.length; j++) {
Method method;
try {
method = clazz.getMethod(methods[j]);
if (method == null) {
continue; // 跳出本次循环
}
Object value = method.invoke(object, null);
System.out.println(value);
row.createCell(j).setCellValue(value + "");
} catch (Exception e) {
e.printStackTrace();
}
}
index++;
}
return sheet;
}
/**
* 塞入普通数据--绑定样式
*
* @param sheet 指定sheet
* @param index 创建表格起始行
* @param list 数据源--泛型随便填,如果没有则obj
* @param methods 需要显示的数据,顺序安排
* @return 组建结束的sheet
*/
public static HSSFSheet addCellDetail(HSSFSheet sheet, int index, List<Object> list, String[] methods, HSSFCellStyle style) {
Class clazz = list.get(0).getClass();
for (int i = 0; i < list.size(); i++) {
Object object = list.get(i);
HSSFRow row = sheet.createRow(index); // 创建行
for (int j = 0; j < methods.length; j++) {
Method method;
try {
method = clazz.getMethod(methods[j]);
if (method == null) {
continue; // 跳出本次循环
}
Object value = method.invoke(object, null);
System.out.println(value);
HSSFCell cell = row.createCell(j);
cell.setCellValue(value + "");
cell.setCellStyle(style);
} catch (Exception e) {
e.printStackTrace();
}
}
index++;
}
return sheet;
}
/**
* 塞入普通数据--自适应宽度(伪)
*
* @param sheet 指定sheet
* @param index 创建表格起始行
* @param list 数据源--泛型随便填,如果没有则obj
* @param methods 需要显示的数据,顺序安排
* @return 组建结束的sheet
*/
public static HSSFSheet addCellDetailSelfWidth(HSSFSheet sheet, int index, List<Object> list, String[] methods) {
double[] width = new double[methods.length];
Class clazz = list.get(0).getClass();
for (int i = 0; i < list.size(); i++) {
Object object = list.get(i);
HSSFRow row = sheet.createRow(index); // 创建行
for (int j = 0; j < methods.length; j++) {
Method method;
double column = 0;
try {
method = clazz.getMethod(methods[j]);
if (method == null) {
continue; // 跳出本次循环
}
Object value = method.invoke(object, null);
column = checkParState(value.toString()) ? value.toString().length() : value.toString().length() * 1.6;
System.out.println(value + "---" + column);
width[j] = column > width[j] ? column : width[j];
row.createCell(j).setCellValue(value + "");
} catch (Exception e) {
e.printStackTrace();
}
}
index++;
}
setColumn(sheet, width);
return sheet;
}
/**
* 数字字母返回true,汉字返回false
*
* @param s
* @return
*/
public static boolean checkParState(String s) {
char c = s.charAt(0);
int i = (int) c;
if ((i >= 65 && i <= 90) || (i >= 97 && i <= 122) || Character.isDigit(i)) {
return true;
} else {
return false;
}
}
/**
* 设定列宽度
* @param sheet sheet表格
* @param widths 列宽
*/
public static void setColumn(HSSFSheet sheet, double[] widths) {
for (int i = 0; i < widths.length; i++) {
sheet.setColumnWidth(i, Integer.parseInt(new java.text.DecimalFormat("0").format(widths[i] * 300)));
}
}
/**
* 设定指定列宽度
* @param sheet sheet表格
* @param widths 列宽
* @param column 列下标
*/
public static void setColumn(HSSFSheet sheet, double[] widths, int...column) {
for (int i = 0; i < column.length; i++) {
sheet.setColumnWidth(column[i], Integer.parseInt(new java.text.DecimalFormat("0").format(widths[i] * 300)));
}
}
标签:sheet,int,Excel,表头,param,HSSFCellStyle,自测,new,red 来源: https://blog.csdn.net/nigdjbfr/article/details/112686022