在开发中经常会遇到系统中的数据需要导成excel的格式,怎么实现?
@Data
@Accessors(chain = true)
@EqualsAndHashCode
@HeadRowHeight(20)
@ColumnWidth(15)
@HeadStyle(horizontalAlignment = HorizontalAlignment.CENTER)
@ContentStyle(horizontalAlignment = HorizontalAlignment.CENTER)
public class NotifyManagementExportDto {
//文号
@ColumnWidth(50)
@ContentStyle(horizontalAlignment = HorizontalAlignment.LEFT)
@ExcelProperty(value = "文号")
private String documentNumber;
//通报名称
@ColumnWidth(50)
@ContentStyle(horizontalAlignment = HorizontalAlignment.LEFT)
@ExcelProperty(value = "通报名称")
private String notifyName;
//业务类型
@ColumnWidth(30)
@ContentStyle(horizontalAlignment = HorizontalAlignment.LEFT, wrapped = true)
@ExcelProperty(value = "业务分类", converter = LineFeedConverter.class)
private String businessClassificationName;
//发文机构
@ColumnWidth(30)
@ContentStyle(horizontalAlignment = HorizontalAlignment.LEFT, wrapped = true)
@ExcelProperty(value = "发文机构", converter = LineFeedConverter.class)
private String organClassificationName;
//发文日期
@ColumnWidth(20)
@ContentStyle(horizontalAlignment = HorizontalAlignment.LEFT)
@ExcelProperty(value = "发文日期")
private String issueDateStr;
//发布状态
@ContentStyle(horizontalAlignment = HorizontalAlignment.LEFT)
@ExcelProperty(value = "发布状态")
private String publishStatus;
}
其中
@HeadRowHeight(20)
@ColumnWidth(15)
@HeadStyle(horizontalAlignment = HorizontalAlignment.CENTER)
@ContentStyle(horizontalAlignment = HorizontalAlignment.CENTER)
这些都是设置excel的行高样式之类的,主要的还是
@ExcelProperty(value = "文号"),他的名字需要和实体类是一个,才能保证数据导的无误
上代码
public List<NotifyManagementExportDto> getNotifyManagementExcelList(NotifyManagementDto notifyManagementDto) {
//调用getNotifyManagementList方法,获取符合条件的案例记录列表,将其保存为HashMap<String, Object>类型的数据结构
HashMap<String, Object> stringObjectHashMap = getNotifyManagementList(notifyManagementDto);
//从HashMap中取出查询到的通报记录列表notifyManagementDtos,保存为List类型
List<NotifyManagementDto> notifyManagementDtos = (List<NotifyManagementDto>) stringObjectHashMap.get("notifyManagementDtoList");
//构建一个新的List对象notifyManagementExportDtoList,用于保存转换后的导出数据
List<NotifyManagementExportDto> notifyManagementExportDtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(notifyManagementDtos)) { // 判断通报管理数据是否为空
for (NotifyManagementDto notifyManagement : notifyManagementDtos) {
NotifyManagementExportDto notifyManagementExportDto = new NotifyManagementExportDto();
//如果是null的情况下,使用--放入空值中
notifyManagementExportDto.setDocumentNumber(notifyManagement.getDocumentNumber() == null ? "--" : notifyManagement.getDocumentNumber());
notifyManagementExportDto.setNotifyName(notifyManagement.getNotifyName() == null ? "--" : notifyManagement.getNotifyName());
notifyManagementExportDto.setBusinessClassificationName(notifyManagement.getBusinessClassificationName() == null ? "--" : notifyManagement.getBusinessClassificationName());
notifyManagementExportDto.setOrganClassificationName(notifyManagement.getOrganClassificationName() == null ? "--" : notifyManagement.getOrganClassificationName());
notifyManagementExportDto.setIssueDateStr(notifyManagement.getIssueDateStr() == null ? "--" : notifyManagement.getIssueDateStr());
if (notifyManagement.getPublishStatus() == null) {
notifyManagementExportDto.setPublishStatus("--");
} else if (notifyManagement.getPublishStatus().equals("0")) {
notifyManagementExportDto.setPublishStatus("未发布");
} else if (notifyManagement.getPublishStatus().equals("1")) {
notifyManagementExportDto.setPublishStatus("已发布");
}
notifyManagementExportDtoList.add(notifyManagementExportDto);
}
}
return notifyManagementExportDtoList;
}
直接调用getNotifyManagementList方法,里面会有排序的方法,所以不需要写,然后在实体类和sql中加入条件,选择导出那条数据(可以多选)名字为List<String>IdList,sql中判断这个IdList不为空,使用id in 进行筛选
<if test="notifyIdList != null">
AND n.id in
<foreach collection="notifyIdList" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
构建一个新的List对象notifyManagementExportDtoList,用于保存转换后的导出数据,通过遍历notifyManagementDtos的数据,实例化Export实体类,将值set进去就可以了,比如
notifyManagementExportDto.setDocumentNumber(notifyManagement.getDocumentNumber() == null ? "--" : notifyManagement.getDocumentNumber());
后面==null?"--":,代表当这个值为空的情况下,excel中显示--。
最后需要一个接口去调用这个方法,在接口中
@PostMapping("/getNotifyManagementExcelList")
//1.
public void getNotifyManagementExcelList(@RequestBody NotifyManagementDto notifyManagementDto, HttpServletResponse response) {
logger.info("通报管理excel导出 start");
try {
//2.
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DateUtil.YYYY_MM_DD_HH_MM_SS);
String fileName = URLEncoder.encode("通报管理" + dateTimeFormatter.format(localDateTime), "UTF-8").replaceAll("\\+", "%20");
//3.
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
//4.
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
response.setHeader("filename", fileName + ".xlsx");
//5.
EasyExcel.write(response.getOutputStream(), NotifyManagementExportDto.class).sheet("Sheet1")
.doWrite(notifyManagementService.getNotifyManagementExcelList(notifyManagementDto));
} catch (IOException e) {
logger.error("通报管理excel统计失败", e);
}
logger.info("通报管理excel导出 end");
}
HttpServletResponse
表示 HTTP 响应对象,用于构造返回的响应- 生成 Excel 文件的文件名,这里使用了当前时间来命名文件,并使用 UTF-8 编码和 URL 编码对文件名进行编码。
- 设置 HTTP 响应的头信息,告诉浏览器返回的是一个 Excel 文件,并设置响应的内容编码为 UTF-8。
- 设置 HTTP 响应头信息中的文件名,浏览器会根据这个头信息提示用户是否要保存文件,并将文件名设置为指定的文件名。第一行中使用了
Content-Disposition
是一个标准的 HTTP 头字段,它表示响应中包含的具体内容要以什么形式展示给用户,这里的filename
指定了文件名;第二行中的filename
是自定义的 HTTP 头信息字段,用于兼容某些浏览器或 HTTP 客户端 -
使用了阿里巴巴开源的 EasyExcel 库来实现 Excel 文件的导出操作。它提供了一个
write
方法用于写入 Excel 文件,doWrite
方法实现实际的数据写入操作。NotifyManagementExportDto
是一个 Java 对象,用于保存要写入 Excel 文件的数据。在实际使用中,这个对象需要转换成 Excel 文件中的行和列。sheet
方法则用于设置 Excel 文件中的工作表的名称。在 try 块中调用write
方法和notifyManagementService.getNotifyManagementExcelList
方法时,EasyExcel 库将会自动将数据写入 Excel 文件。在 catch 块中处理异常。
前端VUE怎么写?
首先要有一个表格table,存放查询出来的数据
<el-table
:data="caseManagement"
@selection-change="handleSelectionChange"
tooltip-effect="dark"
width="100%"
:row-key="(row) => row.id"
ref="caseManagementTable">
<el-table-column type="selection" width="55" :reserve-selection="true">
</el-table-column>
<el-table-column prop="documentNumber" :formatter="tableValueFormatter" label="文号" width="70">
</el-table-column>
</el-table>
在data中定义存放选中的信息(id), multipleSelection: [],
data() {
return {
//查询输入的表单数据
formQueryInfo: {
publishStatus: '', // 发布状态 1 已发布 0 未发布
sortBy: { // 排序
value: 'issue_date',
method: 'desc'
},
start: 0, // 开始行数
pageSize: 20, // 每页数量
documentNumber: '', // 文号
caseTitle: '', // 案例标题
companyAbbreviation: '', // 公司代码、简称
issueOrgan: '', // 发文机构
noticeDateStart: '', // 公告开始日期
noticeDateEnd: '', // 公告结束日期
punishDateStart: '', // 处罚开始日期
punishDateEnd: '', // 处罚结束日期
issueDateStart: '', // 发文开始日期
issueDateEnd: '', // 发文结束日期
punishClassificationId: '', // 处罚类型
businessClassificationId: '', // 业务类型
targetClassificationId: '' // 处罚对象
},
searchSort: {//排序插件数据
sortSelectDataModel: [
{
value: 'company_code',
label: '公司代码'
},
{
value: 'company_name',
label: '公司简称'
}, {
value: 'case_title',
label: '标题'
}, {
value: 'busClassificationName',
label: '业务类型'
}, {
value: 'punClassificationName',
label: '处罚类型'
},
{
value: 'tarClassificationName',
label: '处罚对象'
},
{
value: 'issue_organ',
label: '发文机构'
},
{
value: 'issue_date',
label: '发文日期'
},
{
value: 'notice_date',
label: '公告日期'
},
{
value: 'punish_date',
label: '处罚日期'
}, {
value: 'publish_status',
label: '发布状态'
}
],
defaultSortSelect: {
value: 'issue_date',
method: 'desc'
}
},
// 表格数据
caseManagement: [],
countList: [],
// 选中的当前行
currentRow: {},
// 是否打开新增案例弹出框
showModal: false,
//存放选中的Id
multipleSelection: [],
}
},
最后调用接口
// 导出excel
exportExcel() {
let selection = this.multipleSelection;
if (selection.length === 0) {
this.$message.info('请选择需要导出的案例');
return
}
let caseIdList=[];
if (selection === null && selection.length === 0) {
this.$message.info('请选择需要导出的案例');
}else if(selection!==null && selection.length!==0){
for (const selectionElement of selection) {
caseIdList.push(selectionElement.id);
}
}
let param = {
caseIdList: caseIdList,
sortBy: this.formQueryInfo.sortBy
}
_getCaseManagementExcelList(param).then(res=>{
});
this.$refs.caseManagementTable.clearSelection();
},
首先获取选中的案例信息并判断是否为空,如果为空,则提示用户需要选择案例。
然后遍历选中的案例列表,将每个案例的id保存到caseIdList数组中。
接着根据保存的caseIdList和当前表格中选中的排序方法(this.formQueryInfo.sortBy)作为参数,调用后端接口(_getCaseManagementExcelList)获取案例信息的Excel文件。
由于后端接口返回的文件流可以直接通过浏览器下载,因此在这里我们不需要处理文件流,只需要通过.then()函数来处理请求成功之后的操作,比如清空选中的案例列表(this.$refs.caseManagementTable.clearSelection())。
最后,将结果返回给用户。