Commit 63e3bb66 by guojuxing

导出Excel二级表头添加

parent 071ff681
package com.gic.download.qo; package com.gic.download.qo;
import java.io.Serializable; import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 下载导出文件参数列表类 * 下载导出文件参数列表类
...@@ -50,6 +52,21 @@ public class DownloadExcelQO implements Serializable{ ...@@ -50,6 +52,21 @@ public class DownloadExcelQO implements Serializable{
*/ */
private List<Integer> columnWidth = null; private List<Integer> columnWidth = null;
/**
* 二级表头标题中文,父子关联
*/
private LinkedHashMap<String, List<String>> headerMap;
/**
* 二级表头属性名称
*/
private LinkedHashMap<String, List<String>> propertyNameMap;
/**
* 二级表头需要加密的属性名称
*/
private Map<String, List<String>> needEncryptFieldMap;
public String getTempPath() { public String getTempPath() {
return tempPath; return tempPath;
} }
...@@ -130,4 +147,31 @@ public class DownloadExcelQO implements Serializable{ ...@@ -130,4 +147,31 @@ public class DownloadExcelQO implements Serializable{
this.columnWidth = columnWidth; this.columnWidth = columnWidth;
return this; return this;
} }
public LinkedHashMap<String, List<String>> getHeaderMap() {
return headerMap;
}
public DownloadExcelQO setHeaderMap(LinkedHashMap<String, List<String>> headerMap) {
this.headerMap = headerMap;
return this;
}
public LinkedHashMap<String, List<String>> getPropertyNameMap() {
return propertyNameMap;
}
public DownloadExcelQO setPropertyNameMap(LinkedHashMap<String, List<String>> propertyNameMap) {
this.propertyNameMap = propertyNameMap;
return this;
}
public Map<String, List<String>> getNeedEncryptFieldMap() {
return needEncryptFieldMap;
}
public DownloadExcelQO setNeedEncryptFieldMap(Map<String, List<String>> needEncryptFieldMap) {
this.needEncryptFieldMap = needEncryptFieldMap;
return this;
}
} }
...@@ -6,6 +6,7 @@ import java.util.*; ...@@ -6,6 +6,7 @@ import java.util.*;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import com.gic.download.constants.ExcelExtensionEnum; import com.gic.download.constants.ExcelExtensionEnum;
import com.gic.download.dto.DownloadReportTempDTO; import com.gic.download.dto.DownloadReportTempDTO;
import com.gic.download.qo.DownloadExcelQO; import com.gic.download.qo.DownloadExcelQO;
...@@ -96,6 +97,47 @@ public class DownloadUtils { ...@@ -96,6 +97,47 @@ public class DownloadUtils {
} }
/** /**
* 用于二级表头
* @param bean
* @param propertyName
* @return
*/
protected Object getPropertyOfDouble(Object bean, String propertyName) {
try {
return BeanUtils.getProperty(bean, propertyName);
} catch (Throwable e) {
LOGGER.info("bean:" + bean + ",Property:" + propertyName + e.getMessage(), e);
return null;
}
}
protected String convertPropertyOfDouble(Object bean, String propertyName, Object property) {
try {
Class clazz = getPropertyTypeOfDouble(bean, propertyName);
if (Date.class.equals(clazz)) {
//如果是日期类型
SimpleDateFormat format = new SimpleDateFormat("E MMM dd hh:mm:ss z yyyy", Locale.US);
SimpleDateFormat resultFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return resultFormat.format(format.parse(property.toString()));
}
} catch (Exception e) {
LOGGER.info("bean:" + bean + ",Property:" + propertyName + e.getMessage(), e);
return null;
}
return property == null ? "" : property.toString();
}
protected Class getPropertyTypeOfDouble(Object bean, String propertyName) {
try {
return new PropertyUtilsBean().getPropertyType(bean, propertyName);
} catch (Throwable e) {
LOGGER.info("bean:" + bean + ",Property:" + propertyName + e.getMessage(), e);
return null;
}
}
/**
* 数据获取接口 * 数据获取接口
* @param pageNum -- 从0计数 * @param pageNum -- 从0计数
* @return * @return
...@@ -148,26 +190,53 @@ public class DownloadUtils { ...@@ -148,26 +190,53 @@ public class DownloadUtils {
* @param columnWidth
列宽 * @param columnWidth
列宽
* @return void
 * @return void


*/ 
*/
@Deprecated
protected <T> void downloadOfDoubleHeaderTitle(String tempPath, Integer reportId, String fileName, Integer excelExtensionCode, List<HeaderQO> headerList, List<String> propertyNameList, DownloadDataLoader<T> loader, List<String> needEncryptField, List<Integer> columnWidth) throws Exception { protected <T> void downloadOfDoubleHeaderTitle(String tempPath, Integer reportId, String fileName, Integer excelExtensionCode, List<HeaderQO> headerList, List<String> propertyNameList, DownloadDataLoader<T> loader, List<String> needEncryptField, List<Integer> columnWidth) throws Exception {
downloadCommon(new DownloadExcelQO().setTempPath(tempPath).setReportId(reportId).setFileName(fileName) downloadCommon(new DownloadExcelQO().setTempPath(tempPath).setReportId(reportId).setFileName(fileName)
.setExcelExtensionCode(excelExtensionCode).setHeaders(headerList).setPropertyNameList(propertyNameList) .setExcelExtensionCode(excelExtensionCode).setHeaders(headerList).setPropertyNameList(propertyNameList)
.setNeedEncryptField(needEncryptField).setColumnWidth(columnWidth), loader); .setNeedEncryptField(needEncryptField).setColumnWidth(columnWidth), loader);
} }
/**
* 下载文件,2层标题结构
* @Title: downloadForDoubleHeaderTitle

* @Description:

* @author guojuxing
* @param tempPath 临时路径
* @param reportId 报表中心ID
* @param fileName 文件名称
* @param excelExtensionCode Excel文件扩展名 枚举 ExcelExtensionEnum
* @param headerList 表头名称 2层标题结构
* @param propertyNameList 字段名
* @param loader 数据加载类
* @param needEncryptField 需要加密的字段,每一个元素存的是字段,如phone(电话)
* @param columnWidth
列宽
* @return void


*/
protected <T> void downloadForDoubleHeaderTitle(String tempPath, Integer reportId, String fileName, Integer excelExtensionCode, LinkedHashMap<String, List<String>> headerList, LinkedHashMap<String, List<String>> propertyNameList, DownloadDataLoader<T> loader, Map<String, List<String>> needEncryptField, List<Integer> columnWidth) throws Exception {
downloadCommon(new DownloadExcelQO().setTempPath(tempPath).setReportId(reportId).setFileName(fileName)
.setExcelExtensionCode(excelExtensionCode).setHeaderMap(headerList).setPropertyNameMap(propertyNameList)
.setNeedEncryptFieldMap(needEncryptField).setColumnWidth(columnWidth), loader);
}
private <T> void downloadCommon(DownloadExcelQO param, DownloadDataLoader<T> loader) throws Exception { private <T> void downloadCommon(DownloadExcelQO param, DownloadDataLoader<T> loader) throws Exception {
LOGGER.info("下载导出数据参数:{}", JSON.toJSONString(param));
Integer reportId = param.getReportId(); Integer reportId = param.getReportId();
String fileName = param.getFileName(); String fileName = param.getFileName();
Integer excelExtensionCode = param.getExcelExtensionCode(); Integer excelExtensionCode = param.getExcelExtensionCode();
List<String> headerList = param.getHeaderList(); List<String> headerList = param.getHeaderList();
List<HeaderQO> headers = param.getHeaders();
List<String> propertyNameList = param.getPropertyNameList(); List<String> propertyNameList = param.getPropertyNameList();
List<String> needEncryptField = param.getNeedEncryptField(); List<String> needEncryptField = param.getNeedEncryptField();
String tempPath = param.getTempPath(); String tempPath = param.getTempPath();
//是否是2层标题结构 //是否是2层标题结构
boolean isDoubleHeaderTitle = CollectionUtils.isNotEmpty(headers); LinkedHashMap<String, List<String>> headerMap = param.getHeaderMap();
LinkedHashMap<String, List<String>> propertyNameMap = param.getPropertyNameMap();
Map<String, List<String>> needEncryptFieldMap = param.getNeedEncryptFieldMap();
boolean isDoubleHeaderTitle = headerMap != null && !headerMap.isEmpty();
if (StringUtils.isEmpty(fileName) || loader == null || CollectionUtils.isEmpty(propertyNameList)) { if (StringUtils.isEmpty(fileName) || loader == null) {
throw new RuntimeException("参数错误。FileName:" + fileName + ",DataLoader:" + loader + ",PropertyName:" + propertyNameList); throw new RuntimeException("参数错误。FileName:" + fileName + ",DataLoader:" + loader);
} }
// 获取输出流,设置content-type等头域 // 获取输出流,设置content-type等头域
//final OutputStream out = getResponseStream(response ,fileName); //final OutputStream out = getResponseStream(response ,fileName);
...@@ -203,7 +272,13 @@ public class DownloadUtils { ...@@ -203,7 +272,13 @@ public class DownloadUtils {
} }
}; };
writeOutputStream(loader, propertyNameList, writer, needEncryptField, reportId); if (isDoubleHeaderTitle) {
//二级表头处理
writeOutputStreamOfDoubleHeader(loader, propertyNameMap, writer, needEncryptFieldMap, reportId);
} else {
writeOutputStream(loader, propertyNameList, writer, needEncryptField, reportId);
}
// 写入excel // 写入excel
if (isDoubleHeaderTitle) { if (isDoubleHeaderTitle) {
CellStyle style = workbook.createCellStyle(); CellStyle style = workbook.createCellStyle();
...@@ -211,7 +286,7 @@ public class DownloadUtils { ...@@ -211,7 +286,7 @@ public class DownloadUtils {
style.setAlignment(HorizontalAlignment.CENTER); style.setAlignment(HorizontalAlignment.CENTER);
// 指定单元格垂直居中对齐 // 指定单元格垂直居中对齐
style.setVerticalAlignment(VerticalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER);
if (!ExcelUtils.setHeaderTitle(style, sheet, param.getColumnWidth(), headers, rows)) { if (!ExcelUtils.doubleHeaderTitle(style, sheet, param.getColumnWidth(), headerMap, rows)) {
throw new IOException("设置导出文件内容失败。"); throw new IOException("设置导出文件内容失败。");
} }
} else { } else {
...@@ -298,6 +373,23 @@ public class DownloadUtils { ...@@ -298,6 +373,23 @@ public class DownloadUtils {
return out; return out;
} }
private void test() {
LinkedHashMap<String, List<String>> headerMap = new LinkedHashMap<>(16);
headerMap.put("测试1", null);
headerMap.put("域名2", Arrays.asList("门店1", "门店2"));
headerMap.put("域名3", Arrays.asList("门店1", "门店2"));
LinkedHashMap<String, List<String>> headerPropertyNameMap = new LinkedHashMap<>(16);
headerPropertyNameMap.put("test1", null);
headerPropertyNameMap.put("2", Arrays.asList("store1", "store2"));
headerPropertyNameMap.put("3", Arrays.asList("store1", "store2"));
Map<String, List<String>> needEncryptFieldMap = new HashMap<>(16);
needEncryptFieldMap.put("test1", null);
needEncryptFieldMap.put("2", Arrays.asList("store1"));
needEncryptFieldMap.put("3", Arrays.asList("store1"));
List<Map<String, Object>> dataList = new ArrayList<>();
}
protected <T> void writeOutputStream(DownloadDataLoader<T> loader, List<String> propertyNames, protected <T> void writeOutputStream(DownloadDataLoader<T> loader, List<String> propertyNames,
Writer writer, List<String> needEncryptField, Integer reportId) throws Exception { Writer writer, List<String> needEncryptField, Integer reportId) throws Exception {
...@@ -345,6 +437,78 @@ public class DownloadUtils { ...@@ -345,6 +437,78 @@ public class DownloadUtils {
} }
protected <T> void writeOutputStreamOfDoubleHeader(DownloadDataLoader<T> loader, LinkedHashMap<String, List<String>> propertyNames,
Writer writer, Map<String, List<String>> needEncryptField, Integer reportId) throws Exception {
DownloadReportTempDTO tempReport = DataDownloadUtils.getByReportId(reportId);
//是否是否加密处理
boolean isNeedEncrypt = tempReport != null && tempReport.getDataType().intValue() != 1;
boolean hasNeedEncryptField = needEncryptField != null && !needEncryptField.isEmpty();
int pageNum = 1;
int maxLength = 102400;
while (maxLength -- > 0) {
// 分页获取数据
List<T> objList = null;
try {
objList = loader.getDownloadData(pageNum++);
} catch (Exception e) {
LOGGER.error("获得到处数据异常:{}",e.getMessage(), e);
}
if (CollectionUtils.isEmpty(objList)) {
break;
}
for (T bean : objList) {
if (bean == null) {
continue;
}
//查询的数据对象,格式转换
Map<String, Object> obj = (Map<String, Object>) bean;
Collection<String> result = new ArrayList<String>();
// 遍历指定属性
for (Map.Entry<String, List<String>> entry : propertyNames.entrySet()) {
// 获得属性值 (表头第二层数据)
List<String> propertyValue = entry.getValue();
//数据对象的value
Object objValue = obj.get(entry.getKey());
if (CollectionUtils.isEmpty(propertyValue)) {
//如果是空,说明只有一层
String value = Optional.ofNullable(objValue).orElse("").toString();
if (isNeedEncrypt && hasNeedEncryptField) {
if (needEncryptField.containsKey(entry.getKey())) {
value = encrypt(value);
}
}
result.add(value);
} else {
//如果不为空,说明是二层结构,则
for (String pro : propertyValue) {
// 获得属性值
Object property = loader.getPropertyOfDouble(objValue, pro);
// 将属性值转换成字符串
String convertValue = loader.convertPropertyOfDouble(objValue, pro, property);
if (isNeedEncrypt && hasNeedEncryptField) {
boolean hasProperty = needEncryptField.containsKey(entry.getKey())
&& CollectionUtils.isNotEmpty(needEncryptField.get(entry.getKey()))
&& needEncryptField.get(entry.getKey()).contains(pro);
if (hasProperty) {
convertValue = encrypt(convertValue);
}
}
result.add(convertValue);
}
}
}
if (CollectionUtils.isEmpty(result)) {
continue;
}
writer.write(result);
}
}
}
private static String encrypt(String data) { private static String encrypt(String data) {
if (StringUtils.isBlank(data)) { if (StringUtils.isBlank(data)) {
return data; return data;
......
...@@ -144,6 +144,7 @@ public class ExcelUtils { ...@@ -144,6 +144,7 @@ public class ExcelUtils {
return true; return true;
} }
@Deprecated
public static boolean setHeaderTitle(CellStyle cellStyle, Sheet sheet, List<Integer> columnWidth, List<HeaderQO> headerList, List<?> content) { public static boolean setHeaderTitle(CellStyle cellStyle, Sheet sheet, List<Integer> columnWidth, List<HeaderQO> headerList, List<?> content) {
if (sheet == null) { if (sheet == null) {
logger.info("sheet is null"); logger.info("sheet is null");
...@@ -193,6 +194,57 @@ public class ExcelUtils { ...@@ -193,6 +194,57 @@ public class ExcelUtils {
return true; return true;
} }
public static boolean doubleHeaderTitle(CellStyle cellStyle, Sheet sheet, List<Integer> columnWidth, LinkedHashMap<String, List<String>> headerMap, List<?> content) {
if (sheet == null) {
logger.info("sheet is null");
return false;
}
// 设置sheet格式
setSheetStyle(sheet, columnWidth);
Row row1 = sheet.createRow(0);
Row row2 = sheet.createRow(1);
int n = 0;
for (Map.Entry<String, List<String>> entry : headerMap.entrySet()) {
Cell cell1 = row1.createCell(n);
List<String> sonHeader = entry.getValue();
String value = entry.getKey();
cell1.setCellValue(value);
cell1.setCellStyle(cellStyle);
//2层标题
if (CollectionUtils.isEmpty(sonHeader)) {
//单标题
Cell cell2 = row2.createCell(n);
cell2.setCellStyle(cellStyle);
sheet.addMergedRegion(new CellRangeAddress(0, 1, n, n));
n++;
continue;
}
//创建第一行大标题
sheet.addMergedRegion(new CellRangeAddress(0, 0, n, (n + sonHeader.size() - 1)));
//赋值
for (int j = 0, sonLength = sonHeader.size(); j < sonLength; j ++) {
Cell cell2 = row2.createCell(n++);
cell2.setCellStyle(cellStyle);
cell2.setCellValue(sonHeader.get(j));
}
}
// 如果内容为空 则退出
if (content == null || content.isEmpty()) {
logger.info("content is null,cannot write excel");
return true;
}
int indexRow = 2;
for (Object rowContent : content) {
Row row = sheet.createRow(indexRow++);
setRowInfo(row, rowContent);
}
return true;
}
/** /**
* 導出到excel * 導出到excel
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment