Java ⽤POI 导出Excel 合并单元格、字体、居中样式
1、引⼊maven依赖
2、此处我们以合并多⾏数据为例,效果如下:
3、⾸先创建⼀个⼯作簿
1
<dependency>2
<groupId>org.apache.poi</groupId>3
<artifactId>poi</artifactId>4 <version>4.1.0</version>5 </dependency>
1
HSSFWorkbook wb = new HSSFWorkbook();2
HSSFFont blackFont = getExportFont(wb);3
HSSFCellStyle cellStyle = wb.createCellStyle();4
5
private HSSFFont getExportFont(HSSFWorkbook wb) {6
HSSFFont blackFont = wb.createFont();7
blackFont.setColor(HSSFColor.Index());8
blackFont.setFontName("微软雅⿊"); // 设置字体颜⾊9
blackFont.setFontHeightInPoints((short) 12);10 return blackFont;11 }
添加样式:
⼀、设置背景⾊:
cellStyle.setFillForegroundColor((short) 13);// 设置背景⾊
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
⼆、设置边框:
cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
三、设置居中:
cellStyle.setAlignment(HorizontalAlignment.CENTER); //⽔平居中
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
四、设置字体:
HSSFFont font = wb.createFont();
font.setFontName("⿊体");
font.setFontHeightInPoints((short) 16);//设置字体⼤⼩
HSSFFont font2 = wb.createFont();
font2.setFontName("仿宋_GB2312");
font2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显⽰
font2.setFontHeightInPoints((short) 12);
cellStyle.setFont(font);//选择需要⽤到的字体格式
五、设置列宽: sheet.setColumnWidth(0, 3766);
//第⼀个参数代表列id(从0开始),第2个参数代表宽度值 参考 :"2012-08-10"的宽度为2500
六、设置⾃动换⾏: cellStyle.setWrapText(true);//设置⾃动换⾏
4、在创建⼀个空的Sheet页,如果要创建多个分页,遍历添加即可
1 int rowNum = 0;
2 HSSFSheet sheet = wb.createSheet("Sheet1的标题");
3 HSSFRow row = ateRow(rowNum++);
4 row.setHeight(new Short("1024")); // 设置第⼀⾏标题的⾏⾼
5 Map<String,Integer> fieldIndexMap = new HashMap<>();
6// 遍历绑定标题
7int cellNum = 0;
8// titleMap⾥存的是标题集合{"ID":"ID","作者":"author","邮箱":"email","地址":"address","毕业院校":"education_school","出版书籍":"book","出版社":"publish","出版
9 for (String key : titleMap.ketSet()) {
10 sheet.setColumnWidth(cellNum, 6000); // 设置列宽,可以根据不同的内容⾃定义宽度
11 cell = getCellWithValue(cell, cellNum, fieldList[i], blackFont, cellStyle, row);
12 fieldIndexMap.(key), cellNum); // 存放标题名称和列号的对应关系,为了后⾯内容绑定的时候使⽤
13 cellNum++;
14 }
15
16// 将列的值绑定到列对象上
17 private HSSFCell getCellWithValue(HSSFCell cell, int cellNum, String value, HSSFFont font, HSSFCellStyle cellStyle, HSSFRow row) {
18 cell = ateCell(cellNum);
19 HSSFRichTextString hssfRichTextString = new HSSFRichTextString(value);
20 hssfRichTextString.applyFont(0, value.length(), font);
21 cell.setCellValue(hssfRichTextString);
22 cell.setCellStyle(cellStyle);
23 return cell;
24 }
到此处,标题⾏已经⽣成好了,接下来⽣成内容⾏。
⾸先:假定我们的数据是JSON数组格式的,内容如下:
[{
"ID": "1",
"author": "张三",
"email": "1888888@163",
"address": "北京中关村",
"education_school": "北京⼤学",
"book_info": [
{
"book": "Java⼊门到精通",
"publish": "⼈民出版社",
"publish_time": "2020/5/18"
},{
"book": "Mysql底层原理",
"publish": "⼈民出版社",
"publish_time": "2020/5/19"
},
........
]
},
........
]
根据上⾯的JSON数组数据进⾏遍历,其中book_info⾥⾯存的是出版书籍、出版社和出版时间字段,这⾥就是⼀个⼈会对应多条数据情htmlborder
况,那么就需要将书籍属于同⼀个⼈的个⼈信息⾏进⾏单元格合并,也就是⾏合并。
这⾥使⽤CellRangeAddress对象:
CellRangeAddress cellRangeAddress= new CellRangeAddress(firstRow ,lastRow ,firstColumn ,lastColumn);
参数分别为:起始⾏号,终⽌⾏号, 起始列号,终⽌列号
1 List<JSONObject> sourceMapList = JSONArray.parseArray(dataJson); // dataJson为上⾯的JSON数组数据
2 for (JSONObject jsonObject: sourceMapList) {
3 // 获取当前作者有多少本书,如果⼤于1本,则需要合并单元格
4 List<JSONObject > bookInfoList= JSONArray.parseArray(String.("book_info")));
5 if(bookInfoList.size() > 1){
6 // 这⾥的rowNum 在上⾯创建完标题⾏后变为1,因为本例中需要将表格前五列的⾏按照书本的数量进⾏(⾏的合并)
7 // 假如⼀个作者有三本书,在遍历完这个作者所有书的时候,rowNum将变成当前的rowNum + 3
8 sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + bookInfoList.size() -1, 0,0));
9 sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + bookInfoList.size() -1, 1,1));
10 sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + bookInfoList.size() -1, 2,2));
11 sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + bookInfoList.size() -1, 3,3));
12 sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + bookInfoList.size() -1, 4,4));
13 }
14 row = ateRow(rowNum);
15 // 接下来根据各个列的值绑定到cell对象就⾏了
16 for (String key : personMap.keySet()) {
17 if("book_info".equals(key)){
18 // 书籍信息的⾏没有合并,这⾥需要在遍历的时候,将rowNum设置根据书籍数量⾃增
19 HSSFRow sheetRow = null;
20 for (int i = 0; i < bookInfoList.size(); i++) {
21 sheetRow = ateRow(rowNum);
22 JSONObject jsonBook = (i);
23 for (String feedKey: jsonBook.keySet()) {
24 cell = getCellWithValue(cell, (feedKey), String.(feedKey)), blackFont, cellStyle, sheetRow);
25 }
26 rowNum++;
27 }
28 }else {
29 cell = getCellWithValue(cell, (feedKey), String.(feedKey)), blackFont, cellStyle, sheetRow);
30 }
31
32 }
最后⼀步:导出
1/**
2* wb ⼯作簿
3* filename 导出的⽂件名
4*/
5export(response, request, wb, OutputStream(), filename);
6
7 public static void export(HttpServletResponse resp, HttpServletRequest request, HSSFWorkbook work, OutputStream bos, String filename) throws IOExcep
8 String header = Header("User-Agent");
9 if (ains("Firefox")) {
10 BASE64Encoder base = new BASE64Encoder();
11 filename = "=?utf-8?B?" + Bytes(StandardCharsets.UTF_8)) + "?=";
12 } else {
13 filename = de(filename, "UTF-8").replaceAll("\\+", "%20");
14 }
15 resp.setContentType("application/vnd.ms-excel");
16 resp.addHeader("Content-Disposition", "attachment;fileName=" + filename);
17 work.write(bos);
18 work.close();
19 bos.flush();
20 bos.close();
21 }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论