1、实现效果图
2、设计思路
如上图所示,可以将页面分为3大部分,如下:
- 【CSDN睡竹】为大标题部分,设计为一个独立的表格,该表格不能设置表头,且表格内容部分只生成一行数据,数据内容为显示的“CSDN睡竹”
- 【截止日期、板块内容】为表头备注栏部分,同上,设计为一个独立的表格,该表格不能设置表头,且表格内容部分只生成一行数据,数据内容为显示的“截止日期:2022/07/05
版块内容:用户信息”,一行内换行操作是通过”\n“实现的。 - 【表格】是第三部分,这是一个拥有表头的完整表格。不使用easyExcel的填充方式,直接通过代码实现。
话不多说,直接上代码:
3、实现代码(基于springboot v2.7.1)
3.1、以下是controller层代码:
只是简单的写了一个下载接口,调用service
package com.shuizhu.controller;
import com.shuizhu.service.ExcelServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @睡竹
*/
@Controller
public class ExcelController {
@Autowired
private ExcelServiceImpl service;
@PostMapping("/export")
public void downExcel(HttpServletRequest reuqest, HttpServletResponse response){
service.downExcel(reuqest,response);
}
}
3.2、service代码【关键部分】
package com.shuizhu.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shuizhu.domain.UsersDTO;
import com.shuizhu.util.CustomSheetWriteHandler;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* 睡竹
*/
@Service
public class ExcelServiceImpl {
/**
* Excel下载
*/
public void downExcel(HttpServletRequest reuqest, HttpServletResponse response){
ServletOutputStream out = null;
ExcelWriter build = null;
try {
/**(1)、创建Excel核心对象 */
out = response.getOutputStream();
build = EasyExcel.write(out).build();
// 创建sheet 0表示:文件中第1个sheet页 || CustomSheetWriteHandler是去除网格线
WriteSheet sheet = EasyExcel.writerSheet(0, "测试的sheet名称").registerWriteHandler(
new CustomSheetWriteHandler()).build();
/**(2)、创建Excel页面的数据 【手动创建,工作中,这一部分是动态获取的】*/
//1、表头数据【最上面的标题】 --topicData
List<List<Object>> topicData = new ArrayList<>();
ArrayList<Object> list1 = new ArrayList<>();
list1.add("CSDN睡竹");
topicData.add(list1);
//2、表头备注栏【截止日期、板块内容】--secondData
// 硬代码生成时间和版块内容【工作中,这里是动态生成的】
String tableTime = "2022/07/05";
String sectionContent = "用户信息";
List<List<Object>> secondData = new ArrayList<>();
List<Object> list2 = new ArrayList<>();
list2.add("截止日期:" + tableTime + " \n版块内容:" + sectionContent);
secondData.add(list2);
//3、生成数据表格的标题栏内容【这里的元素个数必须与表格保持一致】
List<List<String>> head = new ArrayList<>();
List<String> head1 = new ArrayList<>();
head1.add("用户编号");
List<String> head2 = new ArrayList<>();
head1.add("用户编号");
List<String> head3 = new ArrayList<>();
head1.add("用户编号");
head2.add("用户名称");
head3.add("用户年龄");
head.add(head1);
head.add(head2);
head.add(head3);
//4、获取数据表格中的数据
List<List<Object>> data = getData();
//5、获取数据表格的总列数,下面需要用到
int size = data.get(0).size();
/**(3)、设置3个表格的样式 */
//1、设置表头样式【最上面的标题】
/**
* 1.1、 合并单元格 【四个参数】
* 参数1:合并开始的第一行 【0:表示第一行】
* 参数2:和平结束的最后一行 【0:表示第一行,0-0=0,表示没有合并行】
* 参数3:合并开始的第一列 【0:表示第一列】
* 参数4:合并开始的最后一列 【size-1:表示合并的列数与数据表格的列数一致】
*/
OnceAbsoluteMergeStrategy mergeStrategy = new OnceAbsoluteMergeStrategy(0, 0, 0, size - 1);
//1.2、设置内容居中
WriteCellStyle contentStyle = new WriteCellStyle();
//垂直居中
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//水平居中
contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
WriteFont writeFont = new WriteFont();
//加粗
writeFont.setBold(true);
//字体大小为16
writeFont.setFontHeightInPoints((short) 16);
contentStyle.setWriteFont(writeFont);
// 单元格策略 参数1为头样式【不需要头部,设置为null】,参数2位表格内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(null, contentStyle);
//2、设置表头备注栏样式【截止日期、板块内容】
/**
* 2.1、合并单元格
* 两个1表示合并在第二行,且没有合并行
* 从第一列开始,合并至数据表格的总列数(长度)
*/
OnceAbsoluteMergeStrategy mergeStrategy2 = new OnceAbsoluteMergeStrategy(1, 1, 0, size - 1);
//2。1、单元格样式
WriteCellStyle contentStyle2 = new WriteCellStyle();
// 设置内容自动换行
contentStyle2.setWrapped(true);
// 字体样式
WriteFont writeFont2 = new WriteFont();
writeFont2.setFontHeightInPoints((short) 10);
contentStyle2.setWriteFont(writeFont2);
HorizontalCellStyleStrategy horizontalCellStyleStrategy2 = new HorizontalCellStyleStrategy(null, contentStyle2);
//3、设置数据表格的样式
// ---------- 头部样式 ----------
WriteCellStyle headStyle = new WriteCellStyle();
// 字体样式
WriteFont headFont = new WriteFont();
headFont.setFontHeightInPoints((short) 11);
headStyle.setWriteFont(headFont);
// 背景颜色
headStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
headStyle.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
// ---------- 内容样式 ----------
WriteCellStyle bodyStyle = new WriteCellStyle();
// 字体样式
WriteFont bodyFont = new WriteFont();
bodyFont.setFontHeightInPoints((short) 10);
bodyStyle.setWriteFont(bodyFont);
// 设置边框
// bodyStyle.setBorderTop(BorderStyle.DOUBLE);
bodyStyle.setBorderLeft(BorderStyle.THIN);
bodyStyle.setBorderRight(BorderStyle.THIN);
bodyStyle.setBorderBottom(BorderStyle.THIN);
// 创建策略
HorizontalCellStyleStrategy dataTableStrategy = new HorizontalCellStyleStrategy(headStyle, bodyStyle);
/**
* (4)、统一设置行高
*/
// 设置表头行高【最上面的标题】 参数1:表头行高为0【不需要表头】 参数2:内容行高为28
SimpleRowHeightStyleStrategy rowHeightStrategy1 = new SimpleRowHeightStyleStrategy((short) 0, (short) 28);
// 设置表头备注栏行高【截止日期、板块内容】
SimpleRowHeightStyleStrategy rowHeightStrategy2 = new SimpleRowHeightStyleStrategy((short) 0, (short) 25);
// 设置数据表格的行高 null表示使用原来的行高
SimpleRowHeightStyleStrategy rowHeightStrategy3 = new SimpleRowHeightStyleStrategy( null, (short) 18);
/**(5)、生成页面中的3个表格
* 0 , 1 , 2 是表格的排序(从上往下)
* 上面设置的样式,合并。。。都需要在这里关联对应的表格
*/
// 生成表格1 ----页面中最上方的大标题
WriteTable topicTable = EasyExcel.writerTable(0).registerWriteHandler(rowHeightStrategy1).registerWriteHandler(mergeStrategy).registerWriteHandler(horizontalCellStyleStrategy).needHead(false).build();
// 生成表格2 ----表头备注栏【截止日期、板块内容】
WriteTable secondTable = EasyExcel.writerTable(1).registerWriteHandler(rowHeightStrategy2).registerWriteHandler(mergeStrategy2).registerWriteHandler(horizontalCellStyleStrategy2).needHead(false).build();
// 生成表格3 ----user表格
WriteTable dataTable = EasyExcel.writerTable(2).registerWriteHandler(rowHeightStrategy3).registerWriteHandler(dataTableStrategy).head(head).needHead(true).build();
/**(6)、把数据填充至各个表格 */
build.write(topicData, sheet, topicTable);
build.write(secondData, sheet, secondTable);
build.write(data, sheet, dataTable);
/**(7) 生成文件 */
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-disposition", "attachment;filename=" + "测试Excel" + ".xlsx");
} catch (Exception e) {
e.printStackTrace();
/**
* 前后端处理下载失败异常
* 该部分必须与【流关闭操作】处于同一 【try-catch-finally】中,否则无法返回错误信息给前端
*/
response.reset();
response.setHeader("content-type", "text/html;charset=utf-8");
try (OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
// 组装JSON
Map<String, Object> map = new HashedMap<>();
map.put("retCode", "9999");
map.put("retMsg", "Excel下载失败:" + e.getMessage());
String json = new ObjectMapper().writeValueAsString(map);
if (!ObjectUtils.isEmpty(writer) && !ObjectUtils.isEmpty(json)) {
//返回错误信息给前端
writer.write(json);
writer.flush();
}
} catch (Exception e2) {
throw new ClassCastException("response.getOutputStream()语句异常");
}
}finally {
//关闭所有的流
build.finish();
if (!ObjectUtils.isEmpty(out)) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 模拟数据库查询,获取user数据
*/
public List<UsersDTO> getUsers(){
List<UsersDTO> users = new ArrayList<>();
for (int i = 0; i < 5; i++) {
UsersDTO usersDTO = new UsersDTO();
usersDTO.setUserId("1000" + i);
usersDTO.setUserName("第" + i + "个用户");
usersDTO.setUserAge(18 + i + "");
users.add(usersDTO);
}
return users;
}
/**
* 不是填充Excel,而是直接往Excel中写
* 需要从users数据集中,获取到value的部分,不需要key
*/
public List<List<Object>> getData(){
List<UsersDTO> users = getUsers();
List<List<Object>> data = new ArrayList<>();
for (UsersDTO user : users) {
//把user转为map
String s = JSONObject.toJSONString(user);
Map jsonMap = JSONObject.parseObject(s, LinkedHashMap.class, Feature.OrderedField);
//获取map中的value,组装成list
Collection values = jsonMap.values();
List<Object> list = new ArrayList<>(values);
data.add(list);
}
return data;
}
}
3.3、去网格的工具类代码
package com.shuizhu.util;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Sheet;
/**
* 自定义sheet样式
*
* @author 睡竹
*/
public class CustomSheetWriteHandler implements SheetWriteHandler {
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
Sheet sheet = writeSheetHolder.getSheet();
// 去除网格线
sheet.setDisplayGridlines(false);
}
}
3.4、pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shuizhu</groupId>
<artifactId>shuizhu-easyexcel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shuizhu-easyexcel</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.80</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
4、完整效果
gitee源码地址:easyExcel生成个性化表格https://download.csdn.net/download/weixin_42675423/85926315
更多easyExcel的样式设计,可以参考我的
easyExcel专栏https://blog.csdn.net/weixin_42675423/category_11774988.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99587.html