hutool 导出复杂excel(动态合并行和列)
java使用poi读取跨行跨列excel
springboot集成easypoi并使用其模板导出功能和遇到的坑
Easypoi Excel模板功能简要说明
easypoi 模板导出兼容合并单元格功能
package com.yymt.utils;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.yymt.common.constants.CommonConstants;
import com.yymt.exception.RRException;
import com.yymt.exception.ResultEnum;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author:xielin
* @Description: 导入(原始方式,支持读取合并)、导出(模板方式含合并)工具类
* @Date:2023/1/11 14:33
* @Version: 1.0
*/
public class ExcelUtil {
private Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 创建工作簿
*
* @param filePath 文件路径
* @return 工作簿
* @throws IOException IO异常
*/
public static Workbook createWorkBook(String filePath) throws IOException {
Assert.isTrue(!FileUtil.exist(filePath), ResultEnum.FILE_NOT_FOUND.getMsg());
//final Workbook workBook = new HSSFWorkbook(new FileInputStream(new File("test.xls")));
if (filePath.toLowerCase().endsWith("xls")) {
Workbook book = new HSSFWorkbook(new FileInputStream(new File(filePath)));
return book;
}
if (filePath.toLowerCase().endsWith("xlsx")) {
Workbook book = new XSSFWorkbook(new FileInputStream(new File(filePath)));
return book;
} else {
throw new RRException("excel格式不正确");
}
}
/**
* 获取表格内容
*
* @param sheet sheet对象
* @param mergedRegionMap 合并单元格信息的Map
* @param row 行对象
* @param rowIndex 行索引
* @param columnIndex 列索引
* @return 获取表格内容
*/
public static String getCellValue(Sheet sheet, Map<String, Integer[]> mergedRegionMap, Row row, int rowIndex, int columnIndex) {
//将列对象的行号和列号+下划线组成key去hashmap中查询,不为空说明当前的cell是合并单元列
String value = "";
Integer[] firstRowNumberAndCellNumber = mergedRegionMap.get(rowIndex + "_" + columnIndex);
//如果是合并单元列,就取合并单元格的首行和首列所在位置读数据,否则就是直接读数据
if (firstRowNumberAndCellNumber != null) {
Row rowTmp = sheet.getRow(firstRowNumberAndCellNumber[0]);
Cell cellTmp = rowTmp.getCell(firstRowNumberAndCellNumber[1]);
value = parseCell(cellTmp);
} else {
value = parseCell(row.getCell(columnIndex));
}
if ("/".equals(value)) {
value = "";
}
return value;
}
/**
* 将存在合并单元格的列记录入put进hashmap并返回
*
* @param sheet sheet对象
* @return
*/
public static Map<String, Integer[]> getMergedRegionMap(Sheet sheet) {
Map<String, Integer[]> result = new HashMap<String, Integer[]>();
//获取excel中的所有合并单元格信息
int sheetMergeCount = sheet.getNumMergedRegions();
//遍历处理
for (int i = 0; i < sheetMergeCount; i++) {
//拿到每个合并单元格,开始行,结束行,开始列,结束列
CellRangeAddress range = sheet.getMergedRegion(i);
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
//构造一个开始行和开始列组成的数组
Integer[] firstRowNumberAndCellNumber = new Integer[]{firstRow, firstColumn};
//遍历,将单元格中的所有行和所有列处理成由行号和下划线和列号组成的key,然后放在hashmap中
for (int currentRowNumber = firstRow; currentRowNumber <= lastRow; currentRowNumber++) {
for (int currentCellNumber = firstColumn; currentCellNumber <= lastColumn; currentCellNumber++) {
result.put(currentRowNumber + "_" + currentCellNumber, firstRowNumberAndCellNumber);
}
}
}
return result;
}
/**
* 解析表格的值
*
* @param cell 单元格对象
* @return 单元格的值
*/
public static String parseCell(Cell cell) {
String temp = "";
if (ObjectUtil.isEmpty(cell)) {
return temp;
}
if (cell.getCellType() == CellType.NUMERIC) {
short format = cell.getCellStyle().getDataFormat();
if (HSSFDateUtil.isCellDateFormatted(cell)) {
SimpleDateFormat sdf = null;
if (format == 20 || format == 32) {
sdf = new SimpleDateFormat("HH:mm");
temp = sdf.format(cell.getDateCellValue());
} else if (format == 14 || format == 31 || format == 57 || format == 58 || format == 176) {
// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
sdf = new SimpleDateFormat("yyyy-MM-dd");
double value = cell.getNumericCellValue();
Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
temp = sdf.format(date);
} else {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
temp = sdf.format(cell.getDateCellValue());
}
} else if (format == 57) {
// HSSFDateUtil.isCellDateFormatted(cell) 存在误判
SimpleDateFormat sdf = null;
// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
sdf = new SimpleDateFormat("yyyy-MM-dd");
double value = cell.getNumericCellValue();
Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
temp = sdf.format(date);
} else {
temp = NumberFormat.getInstance().format(cell.getNumericCellValue());
}
} else if (cell.getCellType() == CellType.STRING) {
temp = cell.getStringCellValue();
} else if (cell.getCellType() == CellType.FORMULA) {
temp = cell.getCellFormula();
} else if (cell.getCellType() == CellType.BOOLEAN) {
temp = String.valueOf(cell.getBooleanCellValue());
}
return StrUtil.trimToEmpty(temp);
}
/**
* 根据dateStr转换成LocalDateTime
* @param dateStr 日期格式字符串
* @return LocalDateTime对象
*/
public static LocalDateTime getLocalDateTime(String dateStr) {
if (StrUtil.isNotBlank(dateStr)) {
// dateStr如:2009年9月 也需要转成日期,默认是1日
if (dateStr.contains("年") && dateStr.contains("月")) {
String year = dateStr.substring(0, dateStr.indexOf("年"));
String month = dateStr.substring(dateStr.indexOf("年") + 1, dateStr.indexOf("月"));
String day = "01";
if (dateStr.contains("日")) {
day = dateStr.substring(dateStr.indexOf("月") + 1, dateStr.indexOf("日"));
}
return LocalDate.of(Convert.toInt(year), Convert.toInt(month), Convert.toInt(day)).atStartOfDay();
}
// dateStr如:2023/1/16
return LocalDate.parse(dateStr).atStartOfDay();
}
return null;
}
public static Integer formatYesOrNo(String str) {
return "是".equals(str) ? 1 : 0;
}
/**
*
* @param mapList 要导出的数据数据map集合
* @param templateExcelName excel模板名称
* @param sheetName sheet名称 (默认是excel模板名称)
* @param fileName 临时导出的文件名
* @return 可访问的文件路径
*/
public static String handleExport(List<Map<String, Object>> mapList, String templateExcelName,String sheetName,String fileName) {
// CommonConstants.TEMP_EXPORT_PATH = "/temp/export/"
FileUtil.mkdir(CommonConstants.TEMP_EXPORT_PATH);
Map<Integer, Map<String, Object>> sheetMap = new HashMap<>();
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("mapList", mapList);
// 第一个sheet
sheetMap.put(0, dataMap);
if (StrUtil.isBlank(sheetName)) {
sheetName = templateExcelName;
}
TemplateExportParams params = new TemplateExportParams("static/template/" + templateExcelName + ".xlsx", sheetName);
Workbook workbook = ExcelExportUtil.exportExcel(sheetMap, params);
String fileAllPath = CommonConstants.TEMP_EXPORT_PATH + fileName;
try (FileOutputStream fos = new FileOutputStream(fileAllPath);) {
workbook.write(fos);
} catch (IOException e) {
throw new RRException(e.getLocalizedMessage());
}
// 压缩文件
// compress(httpServletResponse);
// File zip = ZipUtil.zip(FileUtil.file(CommonConstants.TEMP_EXPORT_PATH));
// FileUtil.del(CommonConstants.TEMP_EXPORT_PATH);
// String filePath = DownloadUtil.getFilePath(zip);
// FileUtil.del(zip);
String filePath = DownloadUtil.getFilePath(new File(fileAllPath));
FileUtil.del(fileAllPath);
return filePath;
}
}
package com.yymt.utils;
import cn.hutool.core.io.IoUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.yymt.exception.RRException;
import com.yymt.modules.system.service.SysUploadFileService;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
public class DownloadUtil {
/**
* 下载文件名重新编码
*
* @param response 响应对象
* @param realFileName 真实文件名
* @return
*/
public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
String percentEncodedFileName = percentEncode(realFileName);
StringBuilder contentDispositionValue = new StringBuilder();
contentDispositionValue.append("attachment; filename=")
.append(percentEncodedFileName)
.append(";")
.append("filename*=")
.append("utf-8''")
.append(percentEncodedFileName);
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
response.setHeader("Content-disposition", contentDispositionValue.toString());
response.setHeader("download-filename", percentEncodedFileName);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setCharacterEncoding("utf-8");
}
/**
* 百分号编码工具方法
*
* @param s 需要百分号编码的字符串
* @return 百分号编码后的字符串
*/
public static String percentEncode(String s) throws UnsupportedEncodingException {
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
return encode.replaceAll("\\+", "%20");
}
public static String getFilePath(File file) {
FileItem fileItem = new DiskFileItemFactory().createItem("file",
MediaType.MULTIPART_FORM_DATA_VALUE,
true,
file.getName());
try (InputStream inputStream = new FileInputStream(file);
OutputStream outputStream = fileItem.getOutputStream()) {
// 流转换
IoUtil.copy(inputStream, outputStream);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid file:" + e, e);
}
CommonsMultipartFile multipartFile = new CommonsMultipartFile(fileItem);
SysUploadFileService uploadFileService = SpringUtil.getBean(SysUploadFileService.class);
R r = uploadFileService.uploadFile(multipartFile, "");
if ( (Integer) r.get("code") != 0) {
throw new RRException("文件下载失败");
}
Map<String,String> data = (Map<String,String>) r.get("data");
return data.get("filePath");
}
}
@Transactional(rollbackFor = Exception.class)
public void importBatch(FilePathParams filePathParams) {
// 修改换成真实文件路径
String filePath = webUploadBase + filePathParams.getFilePath();
Workbook workBook = null;
List<SchoolBuildingUseSaveParam> list = new ArrayList<>();
// 上一次读取的序号(用户去除重复读取数据)
Integer lastNo = null;
// 序号是否相同的数据
Boolean isSameData;
try {
workBook = ExcelUtil.createWorkBook(filePath);
//获取第一个sheet
Sheet sheet = workBook.getSheetAt(0);
//获取合并单元格信息的hashmap
Map<String, Integer[]> mergedRegionMap = ExcelUtil.getMergedRegionMap(sheet);
//从excel的第7行索行开始,遍历到最后一行(标题行,直接跳过不读取)
for (int i = 6; i < sheet.getLastRowNum(); i++) {
int j = 0;
isSameData = Boolean.FALSE;
// 拿到excel的行对象
Row row = sheet.getRow(i);
if (row == null) {
break;
}
SchoolBuildingUseSaveParam entity = null;
// 序号
Integer no = Convert.toInt(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
if (ObjectUtil.isEmpty(no)) {
break;
}
if (Objects.equals(no, lastNo)) {
isSameData = Boolean.TRUE;
} else {
lastNo = no;
}
if (isSameData) {
entity = list.get(list.size() - 1);
} else {
entity = new SchoolBuildingUseSaveParam();
// 校区名称
entity.setSchoolName(DicUtil.findCodeByTypeAndValue(DictTypeConstants.CAMPUS_NAME, ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++)));
// 建筑物名称
entity.setBuildingName(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
// 取得方式
entity.setAcquisitionMethod(DicUtil.findCodeByTypeAndValue(DictTypeConstants.SCHOOL_BUILDING_USE_MANAGEMENT_ACQUISITION_METHOD, ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++)));
// 取得日期
entity.setAcquisitionDate(ExcelUtil.getLocalDateTime(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++)));
// 权属人
entity.setPropertyOwner(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
// 资产价值(万元)
entity.setPropertyValue(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 地上面积(平方米)
entity.setOvergroundArea(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 地下面积(平方米)
entity.setUndergroundArea(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 地上层数
entity.setOvergroundFloors(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 地下层数
entity.setUndergroundFloors(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 房屋权属证明
entity.setHouseOwnershipCertificate(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
// 发证日期
entity.setReleaseDate(ExcelUtil.getLocalDateTime(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++)));
// 房屋所有权证号
entity.setHouseOwnershipNumber(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
// 权属面积(平方米)
entity.setOwnershipArea(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 是否BOT模式(1:是,0:否)
entity.setBotFlag(ExcelUtil.formatYesOrNo(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++)));
// BOT模式期限
entity.setBotDate(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
}
// 使用情况的保存 (从18列使用单位开始读取)
j = 17;
// 学校正在自用
SchoolBuildingUsageSaveParam schoolBuildingUsageSaveParam1 = new SchoolBuildingUsageSaveParam();
schoolBuildingUsageSaveParam1.setUsage(UsageEnum.SCHOOL_PRIVATE_USE.getCode());
schoolBuildingUsageSaveParam1.setUseUnit(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
schoolBuildingUsageSaveParam1.setUsePeopleCount(Convert.toInt(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++)));
schoolBuildingUsageSaveParam1.setUseArea(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 出租出借
SchoolBuildingUsageSaveParam schoolBuildingUsageSaveParam2 = new SchoolBuildingUsageSaveParam();
schoolBuildingUsageSaveParam2.setUsage(UsageEnum.LEND_HIRE.getCode());
schoolBuildingUsageSaveParam2.setFloorRange(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
schoolBuildingUsageSaveParam2.setUseArea(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
// 暂未有效使用
SchoolBuildingUsageSaveParam schoolBuildingUsageSaveParam3 = new SchoolBuildingUsageSaveParam();
schoolBuildingUsageSaveParam3.setUsage(UsageEnum.YET_EFFECTIVE_USE.getCode());
schoolBuildingUsageSaveParam3.setFloorRange(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
schoolBuildingUsageSaveParam3.setUseArea(Convert.toDouble(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++), 0D));
List<SchoolBuildingUsageSaveParam> schoolBuildingUsageSaveParamList = entity.getSchoolBuildingUsageSaveParamList();
if (CollUtil.isEmpty(schoolBuildingUsageSaveParamList)) {
schoolBuildingUsageSaveParamList = new ArrayList<>();
}
if (schoolBuildingUsageSaveParam1.isValidOrNot()) {
schoolBuildingUsageSaveParamList.add(schoolBuildingUsageSaveParam1);
}
if (schoolBuildingUsageSaveParam2.isValidOrNot()) {
schoolBuildingUsageSaveParamList.add(schoolBuildingUsageSaveParam2);
}
if (schoolBuildingUsageSaveParam3.isValidOrNot()) {
schoolBuildingUsageSaveParamList.add(schoolBuildingUsageSaveParam3);
}
entity.setSchoolBuildingUsageSaveParamList(schoolBuildingUsageSaveParamList);
// 删除最后的或新增实体
if (isSameData) {
list.remove(list.size() - 1);
} else {
// 是否老旧危房
entity.setOldHouseFlag(ExcelUtil.formatYesOrNo(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++)));
// 备注
entity.setRemark(ExcelUtil.getCellValue(sheet, mergedRegionMap, row, i, j++));
}
list.add(entity);
}
if (CollUtil.isNotEmpty(list)) {
list.forEach(e -> insertOrUpdateSchoolBuildingUse(e));
}
} catch (Exception e) {
log.error("error", e.getMessage());
throw new RRException("数据导入异常");
} finally {
IoUtil.close(workBook);
}
}
高校校舍使用情况统计表 | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
单位(盖章): 填表人: 部门负责人: 分管校领导: 填表日期: | |||||||||||||||||||||||||
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
序号 | 校区名称 | 建筑物名称 | 取得方式 | 取得日期 | 权属人 | 资产价值(万元) | 建筑面积 | 建筑层数 | 权属情况 | BOT模式 | 使用情况 | 是否 老旧危房 | 备注 | ||||||||||||
地上面积 | 地下面积 | 地上层数 | 地下层数 | 房屋权属证明 | 发证日期 | 房屋所有权证号 | 权属面积 | 是否BOT模式 | BOT模式 期限 | 学校正在自用 | 出租出借 | 暂未有效使用 | |||||||||||||
使用单位 | 使用人数 | 使用面积 | 楼层范围 | 使用面积 | 楼层范围 | 使用面积 | |||||||||||||||||||
{{fe: mapList t.no | t.schoolNameValue | t.buildingName | t.acquisitionMethodValue | fd:(t.acquisitionDate;yyyy年MM月) | t.propertyOwner | t.propertyValue | t.overgroundArea | t.undergroundArea | t.overgroundFloors | t.undergroundFloors | t.houseOwnershipCertificate | fd:(t.releaseDate;yyyy年MM月) | t.houseOwnershipNumber | t.ownershipArea | t.botFlagValue | t.botDate | t.usageList.useUnit1 | t.usageList.usePeopleCount1 | t.usageList.useArea1 | t.usageList.floorRange2 | t.usageList.useArea2 | t.usageList.floorRange3 | t.usageList.useArea3 | t.oldHouseFlagValue | t.remark}} |
@PostMapping("/exportBatch")
@ApiOperation(value = "导出")
public R exportBatch(@Validated @RequestBody SchoolBuildingUseExportParam schoolBuildingUseExportParam) {
return R.ok().put("data", schoolBuildingUseService.exportBatch(schoolBuildingUseExportParam));
}
@ApiModel(description = "校舍使用管理导出参数")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SchoolBuildingUseExportParam {
@ApiModelProperty(value = "部分导出是不能为空")
private List<String> idList;
@ApiModelProperty(value = "导出类型,1:部分导出,2:全部导出")
@NotNull(message = "导出类型不能为空")
private Integer exportType;
}
public String exportBatch(SchoolBuildingUseExportParam schoolBuildingUseExportParam) {
List<String> idList = schoolBuildingUseExportParam.getIdList();
List<Long> idLongList = new ArrayList<>();
if (schoolBuildingUseExportParam.getExportType() == 1) {
Assert.isTrue(ObjectUtil.isEmpty(idList), "请选择要导出的数据");
idLongList = idList.stream().map(Long::parseLong).collect(Collectors.toList());
}
// 查询要导出的数据
List<SchoolBuildingUseEntity> schoolBuildingUseEntityList = list(Wrappers.<SchoolBuildingUseEntity>lambdaQuery()
.in(ObjectUtil.isNotEmpty(idLongList), SchoolBuildingUseEntity::getId, idLongList)
.orderByDesc(SchoolBuildingUseEntity::getUpdateTime));
// Assert.isTrue(CollUtil.isEmpty(schoolBuildingUseEntityList), "暂无数据导出");无数据可以用于下载模板(id传0)
// 转换后的
AtomicReference<Integer> no = new AtomicReference<>(1);
List<Map<String, Object>> mapList = schoolBuildingUseEntityList.stream().map(e -> {
SchoolBuildingUseExportVO schoolBuildingUseExportVO = new SchoolBuildingUseExportVO();
BeanUtil.copyProperties(e, schoolBuildingUseExportVO);
schoolBuildingUseExportVO.setNo(no.getAndSet(no.get() + 1));
schoolBuildingUseExportVO.setBotFlagValue(BotFlagEnum.getValueByCode(e.getBotFlag()));
schoolBuildingUseExportVO.setOldHouseFlagValue(OldHouseFlagEnum.getValueByCode(e.getOldHouseFlag()));
schoolBuildingUseExportVO.setSchoolNameValue(DicUtil.findValueByTypeAndCode(DictTypeConstants.CAMPUS_NAME, e.getSchoolName()));
schoolBuildingUseExportVO.setAcquisitionMethodValue(DicUtil.findValueByTypeAndCode(
DictTypeConstants.SCHOOL_BUILDING_USE_MANAGEMENT_ACQUISITION_METHOD, e.getAcquisitionMethod()));
// 查询使用情况
Map<Integer, List<SchoolBuildingUsageEntity>> collectMap = querySchoolBuildingUsageEntityMapList(e.getId());
if (ObjectUtil.isNotEmpty(collectMap)) {
schoolBuildingUseExportVO.setSchoolPrivateUseList(BeanUtil.copyToList(
collectMap.get(UsageEnum.SCHOOL_PRIVATE_USE.getCode()), SchoolBuildingUsageInfoVO.class));
schoolBuildingUseExportVO.setLendHireList(BeanUtil.copyToList(
collectMap.get(UsageEnum.LEND_HIRE.getCode()), SchoolBuildingUsageInfoVO.class));
schoolBuildingUseExportVO.setYetEffectiveUseList(BeanUtil.copyToList(
collectMap.get(UsageEnum.YET_EFFECTIVE_USE.getCode()), SchoolBuildingUsageInfoVO.class));
// 设置使用情况集合
generateSchoolBuildingUsageExportVOList(schoolBuildingUseExportVO);
}
return BeanUtil.beanToMap(schoolBuildingUseExportVO);
}).collect(Collectors.toList());
// 临时文件名
String fileName = CommonConstants.SCHOOL_BUILDING_USE_TEMPLATE_EXCEL_NAME + StrUtil.UNDERLINE + System.currentTimeMillis() + ".xls";
return ExcelUtil.handleExport(mapList, CommonConstants.SCHOOL_BUILDING_USE_TEMPLATE_EXCEL_NAME, null, fileName);
}
public String exportPropertyCheckCollect(List<Long> propertyCheckCollectIds,
HttpServletResponse httpServletResponse) {
TemplateExportParams params = new TemplateExportParams(
"static/template/资产清查固定资产清查表(含明细、汇总)空表.xls", true,
"附1-" + LocalDate.now().getYear() + "年赣南医学院固定资产清查明细表",
"附2-" + LocalDate.now().getYear() + "年赣南医学院固定资产清查汇总表",
"附3-" + LocalDate.now().getYear() + "年赣南医学院固定资产清查盘盈明细表",
"附4-" + LocalDate.now().getYear() + "年赣南医学院固定资产清查盘亏明细表");
List<PropertyCheckCollect> propertyCheckCollectList = baseMapper.selectBatchIds(propertyCheckCollectIds);
Map<Long, List<PropertyCheckCollect>> listMap = propertyCheckCollectList.stream()
.collect(Collectors.groupingBy(PropertyCheckCollect::getDeptId));
Map<Integer, Map<String, Object>> sheetMap = new HashMap<Integer, Map<String, Object>>();
Map<String, Object> map = new HashMap<String, Object>();
List<Map<String, Object>> maplist = null;
for (Map.Entry<Long, List<PropertyCheckCollect>> listEntry : listMap.entrySet()) {
List<PropertyCheckCollect> checkCollectList = listEntry.getValue();
for (PropertyCheckCollect propertyCheckCollect : checkCollectList) {
int num1 = 0;
// 根据盘点id查询盘点资产关联表
List<PropertyCheckCorr> checkCorrList = propertyCheckCorrMapper.selectList(
Wrappers.<PropertyCheckCorr>lambdaQuery()
.eq(PropertyCheckCorr::getCheckId, propertyCheckCollect.getCheckId()));
PropertyExportVO propertyExportVO = null;
maplist = new ArrayList<Map<String, Object>>();
for (PropertyCheckCorr propertyCheckCorr : checkCorrList) {
map = new HashMap<>();
map.put("year", LocalDateTime.now().getYear());
num1++;
propertyExportVO =
propertyCheckCorrMapper.selectPropertyByPropertyId(
propertyCheckCorr.getPropertyId(), propertyCheckCorr.getCheckId());
map.put("deptName", propertyExportVO.getDeptName());
// 获取资产的存放位置
PropertyVO.PropertyUseInfo propertyUseInfo =
propertyUseService.findPropertyUseInfo(propertyCheckCorr.getPropertyId());
if (propertyUseInfo != null) {
propertyExportVO.setPropertyArea(propertyUseInfo.getPropertyArea());
}
// 盘点数量
propertyExportVO.setCheckNum(checkCorrList.size());
propertyExportVO.setNum(num1);
// 无盈亏
if (CheckStatusEnum.HAVE_INVENTORY.getInventoryStatus() == propertyCheckCorr.getInventoryStatus()) {
propertyExportVO.setNoProfitAndLoss("√");
// 盘盈
} else if (CheckStatusEnum.PROFIT.getInventoryStatus() == propertyCheckCorr.getInventoryStatus()) {
propertyExportVO.setProfit("√");
// 盘亏
} else if (CheckStatusEnum.LOSS.getInventoryStatus() == propertyCheckCorr.getInventoryStatus()) {
propertyExportVO.setLoss("√");
}
JSONObject parseObject = JSONObject.parseObject(JSON.toJSONString(propertyExportVO));
maplist.add(parseObject);
}
map.put("maplist", maplist);
// 第一个sheet
sheetMap.put(0, map);
List<PropertyCheckCorr> checkCorrProfitList = propertyCheckCorrMapper.selectList(
Wrappers.<PropertyCheckCorr>lambdaQuery()
.eq(PropertyCheckCorr::getCheckId, propertyCheckCollect.getCheckId())
.eq(PropertyCheckCorr::getInventoryStatus, CheckStatusEnum.PROFIT.getInventoryStatus()));
map = new HashMap<>();
maplist = new ArrayList<Map<String, Object>>();
map.put("year", LocalDateTime.now().getYear());
JSONObject parseObject = null;
int num3 = 0;
if (CollectionUtils.isNotEmpty(checkCorrProfitList)) {
for (PropertyCheckCorr propertyCheckCorr : checkCorrProfitList) {
propertyExportVO =
propertyCheckCorrMapper.selectPropertyByPropertyId(propertyCheckCorr.getPropertyId(), propertyCheckCorr.getCheckId());
map.put("deptName", propertyExportVO.getDeptName());
// 获取资产的存放位置
PropertyVO.PropertyUseInfo propertyUseInfo =
propertyUseService.findPropertyUseInfo(propertyCheckCorr.getPropertyId());
if (propertyUseInfo != null) {
propertyExportVO.setPropertyArea(propertyUseInfo.getPropertyArea());
}
// 盘点数量
propertyExportVO.setCheckNum(checkCorrList.size());
num3++;
propertyExportVO.setNum(num3);
propertyExportVO.setProfit("√");
parseObject = JSONObject.parseObject(JSON.toJSONString(propertyExportVO));
maplist.add(parseObject);
}
}
map.put("maplist", maplist);
// 第三个sheet
sheetMap.put(2, map);
List<PropertyCheckCorr> checkCorrLossList = propertyCheckCorrMapper.selectList(
Wrappers.<PropertyCheckCorr>lambdaQuery()
.eq(PropertyCheckCorr::getCheckId, propertyCheckCollect.getCheckId())
.eq(PropertyCheckCorr::getInventoryStatus, CheckStatusEnum.LOSS.getInventoryStatus()));
map = new HashMap<>();
maplist = new ArrayList<Map<String, Object>>();
map.put("year", LocalDateTime.now().getYear());
int num4 = 0;
if (CollectionUtils.isNotEmpty(checkCorrLossList)) {
for (PropertyCheckCorr propertyCheckCorr : checkCorrLossList) {
propertyExportVO =
propertyCheckCorrMapper.selectPropertyByPropertyId(
propertyCheckCorr.getPropertyId(), propertyCheckCorr.getCheckId());
map.put("deptName", propertyExportVO.getDeptName());
// 获取资产的存放位置
PropertyVO.PropertyUseInfo propertyUseInfo =
propertyUseService.findPropertyUseInfo(propertyCheckCorr.getPropertyId());
if (propertyUseInfo != null) {
propertyExportVO.setPropertyArea(propertyUseInfo.getPropertyArea());
}
// 盘点数量
propertyExportVO.setCheckNum(checkCorrList.size());
num4++;
propertyExportVO.setNum(num4);
propertyExportVO.setLoss("√");
parseObject = JSONObject.parseObject(JSON.toJSONString(propertyExportVO));
maplist.add(parseObject);
}
}
map.put("maplist", maplist);
// 第四个sheet
sheetMap.put(3, map);
// 组装第二个sheet数据
map = new HashMap<>();
map.put("year", LocalDate.now().getYear());
map.put("deptName", propertyExportVO.getDeptName());
map.put("checkNum", propertyExportVO.getCheckNum());
if (CollectionUtils.isNotEmpty(checkCorrList)) {
// 查询资产的总金额
List<Long> propertyIdList = checkCorrList.stream()
.map(PropertyCheckCorr::getPropertyId).collect(Collectors.toList());
BigDecimal totalMoney = propertyService.sumAllPropertyMoney(propertyIdList);
map.put("totalMoney", totalMoney);
PropertyCheck propertyCheck = propertyCheckService.getById(checkCorrList.get(0).getCheckId());
map.put("checkFinishTime", propertyCheck.getCheckFinishTime());
}
// 查询无盈亏台数
List<PropertyCheckCorr> checkCorrNoProfitAndLossList = propertyCheckCorrMapper.selectList(
Wrappers.<PropertyCheckCorr>lambdaQuery()
.eq(PropertyCheckCorr::getCheckId, propertyCheckCollect.getCheckId())
.eq(PropertyCheckCorr::getInventoryStatus, CheckStatusEnum.HAVE_INVENTORY.getInventoryStatus()));
if (CollectionUtils.isNotEmpty(checkCorrNoProfitAndLossList)) {
map.put("noProfitAndLoss", checkCorrNoProfitAndLossList.size());
List<Long> propertyIds = checkCorrNoProfitAndLossList.stream()
.map(PropertyCheckCorr::getPropertyId).collect(Collectors.toList());
BigDecimal noProfitAndLossMoney = propertyService.sumAllPropertyMoney(propertyIds);
map.put("noProfitAndLossMoney", noProfitAndLossMoney);
} else {
map.put("noProfitAndLoss", 0);
map.put("noProfitAndLossMoney", 0);
}
// 盘盈台数
if (CollectionUtils.isNotEmpty(checkCorrProfitList)) {
map.put("profit", checkCorrProfitList.size());
} else {
map.put("profit", 0);
}
// 盘亏台数 和盘亏总金额
if (CollectionUtils.isNotEmpty(checkCorrLossList)) {
map.put("loss", checkCorrLossList.size());
List<Long> propertyIds = checkCorrLossList.stream()
.map(PropertyCheckCorr::getPropertyId).collect(Collectors.toList());
BigDecimal lossMoney = propertyService.sumAllPropertyMoney(propertyIds);
map.put("lossMoney", lossMoney);
} else {
map.put("loss", 0);
map.put("lossMoney", 0);
}
// 第二个sheet
sheetMap.put(1, map);
Workbook workbook = ExcelExportUtil.exportExcel(sheetMap, params);
File savefile = new File("/tmp/excel/");
if (!savefile.exists()) {
savefile.mkdirs();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream("/tmp/excel/" + propertyCheckCollect.getCollectName()
+ "资产清查固定资产清查表(含明细、汇总)表.xls");
workbook.write(fos);
} catch (IOException e) {
log.error("导出盘点汇总报表异常: {}", e.getLocalizedMessage(), e);
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 压缩文件
// compress(httpServletResponse);
File zip = ZipUtil.zip(FileUtil.file("/tmp/excel/"));
FileUtil.del("/tmp/excel/");
String filePath = DownloadUtil.getFilePath(zip);
FileUtil.del(zip);
return filePath;
}
private void compress(HttpServletResponse httpServletResponse) {
File zip = ZipUtil.zip(FileUtil.file("/tmp/excel/"));
FileUtil.del("/tmp/excel/");
FileInputStream fis = null;
ServletOutputStream outputStream = null;
try {
DownloadUtil.setAttachmentResponseHeader(httpServletResponse,
"资产清查固定资产清查表(含明细、汇总)表.zip");
fis = new FileInputStream(zip);
outputStream = httpServletResponse.getOutputStream();
byte[] buffer = new byte[1024];
int read = -1;
while ((read = fis.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
} catch (IOException e) {
log.error("下载盘点汇总报表异常: {}", e.getLocalizedMessage(), e);
} finally {
try {
if (fis != null) {
fis.close();
}
if (outputStream != null) {
outputStream.close();
}
FileUtil.del(zip);
} catch (IOException e) {
e.printStackTrace();
}
}
}
不使用模板的导出,使用@ExcelCollection可以自动合并单元格
sheet.addMergedRegion(new Region(2,(short)0,3,(short )0));
//跨两行占一列 ce.setCellStyle(style); HSSFCell ce1=row.createCell(1);
//姓名 ce1.setCell
public static void main(String[] args) throws IOException {
export1();
}
@GetMapping("/goods")
public static void export1() throws IOException {
List<UserGoodsDto> userGoodsDtos = new ArrayList<>();
UserGoodsDto userGoodsDto = new UserGoodsDto();
userGoodsDto.setUserName("name1");
List<UserGoods> userGoodsList = new ArrayList<>();
UserGoods userGoods = new UserGoods();
userGoods.setId(1);
userGoods.setGoodsName("name0");
userGoods.setGoodsAddress("add");
userGoods.setCreatedTime(new Date());
UserGoods userGoods2 = new UserGoods();
userGoods2.setId(2);
userGoods2.setGoodsName("name1");
userGoods2.setGoodsAddress("add2");
userGoods2.setCreatedTime(new Date());
userGoodsList.add(userGoods);
userGoodsList.add(userGoods2);
userGoodsDto.setUserGoodsList(userGoodsList);
//***
UserGoodsDto userGoodsDto2 = new UserGoodsDto();
userGoodsDto2.setUserName("name1");
List<UserGoods> userGoodsList2 = new ArrayList<>();
userGoodsList2.add(new UserGoods()
.setId(3)
.setGoodsName("name2")
.setGoodsAddress("add2")
.setCreatedTime(new Date()));
userGoodsList2.add(new UserGoods()
.setId(4)
.setGoodsName("name3")
.setGoodsAddress("add2")
.setCreatedTime(new Date()));
userGoodsDto2.setUserGoodsList(userGoodsList2);
List<UserGoodsTest> userGoodsTestList = new ArrayList<>();
userGoodsTestList.add(new UserGoodsTest()
.setId(4)
.setGoodsName("name3Test")
.setGoodsAddress("add2")
.setCreatedTime(new Date()));
userGoodsDto2.setUserGoodsTestList(userGoodsTestList);
userGoodsDtos.add(userGoodsDto);
userGoodsDtos.add(userGoodsDto2);
System.out.println(userGoodsDtos);
ExportParams exportParams = new ExportParams("双十一客户下单情况", null);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, UserGoodsDto.class, userGoodsDtos);
// ExcelExportEntity excelExportEntity = new ExcelExportEntity();
// ExcelExportUtil.exportExcel(exportParams, , userGoodsDtos);
String fileAllPath = CommonConstants.TEMP_EXPORT_PATH + "1.xls";
try (FileOutputStream fos = new FileOutputStream(fileAllPath);) {
workbook.write(fos);
} catch (IOException e) {
throw new RRException(e.getLocalizedMessage());
}
// ExcelExportUtil.exportExcel(userGoodsDtos,UserGoodsDto.class,"测试",exportParams,response);
}
@Data
@Accessors(chain = true)
class UserGoodsDto {
@Excel(name = "用户名", needMerge = true)
private String userName;
@ExcelCollection(name = "商品")
private List<UserGoods> userGoodsList;
@ExcelCollection(name = "商品2")
private List<UserGoodsTest> userGoodsTestList;
}
@Data
@Accessors(chain = true)
class UserGoods {
private Integer id;
@Excel(name = "商品名")
private String goodsName;
@Excel(name = "收货地址")
private String goodsAddress;
@Excel(name = "下单时间", exportFormat = "yyyy-MM-dd HH:mm:ss")
private Date createdTime;
}
@Data
@Accessors(chain = true)
class UserGoodsTest {
private Integer id;
@Excel(name = "商品名test")
private String goodsName;
@Excel(name = "收货地址test")
private String goodsAddress;
@Excel(name = "下单时间test", exportFormat = "yyyy-MM-dd HH:mm:ss")
private Date createdTime;
}
oodsDto.class,“测试”,exportParams,response);
}
@Data
@Accessors(chain = true)
class UserGoodsDto {
@Excel(name = “用户名”, needMerge = true)
private String userName;
@ExcelCollection(name = “商品”)
private List userGoodsList;
@ExcelCollection(name = “商品2”)
private List userGoodsTestList;
}
@Data
@Accessors(chain = true)
class UserGoods {
private Integer id;
@Excel(name = “商品名”)
private String goodsName;
@Excel(name = “收货地址”)
private String goodsAddress;
@Excel(name = “下单时间”, exportFormat = “yyyy-MM-dd HH:mm:ss”)
private Date createdTime;
}
@Data
@Accessors(chain = true)
class UserGoodsTest {
private Integer id;
@Excel(name = “商品名test”)
private String goodsName;
@Excel(name = “收货地址test”)
private String goodsAddress;
@Excel(name = “下单时间test”, exportFormat = “yyyy-MM-dd HH:mm:ss”)
private Date createdTime;
}