1、为了避免excel下拉框选项过多会导致内容不显示(或者生成的时候报错:String literals in formulas can't be bigger than 255 characters ASCII easyexcel),将下拉框的内容都存储在另一个新建的固定的sheet页,再通过引用公式关联单元格的下拉框内容,从而形成能够存储多数值的下拉框。
2、导出代码(这里演示的是一次性导出多个模板,采用压缩包的形式下载,并且表头是动态的):
-
/**
-
* 导出模板
-
* @param response
-
* @param businessViewId
-
*/
-
@Override
-
public
void
exportTemplate
(HttpServletResponse response, String businessViewId)
throws IOException {
-
String[] split = businessViewId.split(
",");
-
String
zipName
=
"模板.zip";
-
response.setCharacterEncoding(
"utf-8");
-
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
-
response.setHeader(
"Content-Disposition",
"attachment;filename*=UTF-8''" + URLEncoder.encode(zipName,
"UTF-8"));
-
ServletOutputStream
out
= response.getOutputStream();
-
ZipOutputStream
zipOutputStream
=
new
ZipOutputStream(out);
-
for (String viewid : split) {
-
List
field = baseMapper.findBusinessFieldByViewId(viewid);
-
//根据表id查询父表id
-
String
parentId
=
this.findParentIdByViewId(viewid);
-
List
parentFieldList = baseMapper.findBusinessFieldByViewId(parentId);
-
//定义表头
-
List
> headList =
new
ArrayList<>();
-
//定义数据体
-
List
> dataList =
new
ArrayList<>();
-
// 指定标红色的列
-
List
columns = Arrays.asList();
-
// 指定批注
-
HashMap
annotationsMap =
new
HashMap<>();
-
HashMap
> dropDownMap =
new
HashMap<>();
-
//主表字段
-
for (
int
i
=
0;i
-
BusinessField
businessField
= parentFieldList.get(i);
-
headList.add(Lists.newArrayList(businessField.getName()));
-
if (StringUtils.isNotBlank(businessField.getControlType())){
-
if (businessField.getControlType().contains(
"select")){
-
List
tDataDictionaries = tDataDictionaryTempMapper.getNameByPid(businessField.getDictionary());
-
// 存储需要下拉框的值,这里的key是需要设置为下拉框的列数,value是下拉框的值,是list
-
if (tDataDictionaries !=
null && tDataDictionaries.size()>
0) {
-
dropDownMap.put(i,tDataDictionaries);
-
}
-
}
-
}
-
}
-
//子表字段
-
for (
int
i
=
0;i
-
BusinessField
businessField
= field.get(i);
-
headList.add(Lists.newArrayList(businessField.getName()));
-
if (StringUtils.isNotBlank(businessField.getControlType())){
-
if (businessField.getControlType().contains(
"select")){
-
List
tDataDictionaries = tDataDictionaryTempMapper.getNameByPid(businessField.getDictionary());
-
// 存储需要下拉框的值,这里的key是需要设置为下拉框的列数,value是下拉框的值,是list
-
if (tDataDictionaries !=
null && tDataDictionaries.size()>
0){
-
dropDownMap.put(i+parentFieldList.size(),tDataDictionaries);
-
}
-
}
-
}
-
}
-
ExcelWriter
excelWriter
= EasyExcel.write().excelType(ExcelTypeEnum.XLS).build();
-
//构建一个sheet页
-
WriteSheet
writeSheet
= EasyExcel.writerSheet(
"sheet1").build();
-
// TltleHandler titleHandler = new TltleHandler(columns, IndexedColors.RED.index,annotationsMap,dropDownMap);
-
// ExayExcelUtils.writeExcelWithModel(response.getOutputStream(), dataList, headList, "sheet1", (CellWriteHandler) titleHandler);
-
// 头的策略
-
WriteCellStyle
headWriteCellStyle
=
new
WriteCellStyle();
-
// 单元格策略
-
WriteCellStyle
contentWriteCellStyle
=
new
WriteCellStyle();
-
// 初始化表格样式
-
HorizontalCellStyleStrategy
horizontalCellStyleStrategy
=
new
HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
-
// SelectSheetWriteHandler(dropDownMap) 是设置下拉框的类
-
WriteTable
writeTable
= EasyExcel.writerTable(
0).head(headList).registerWriteHandler(horizontalCellStyleStrategy).registerWriteHandler(
new
SelectSheetWriteHandler(dropDownMap)).needHead(Boolean.TRUE).build();
-
excelWriter.write(dataList, writeSheet, writeTable);
-
// 开始导出
-
// excelWriterSheetBuilder.doWrite(dataList);
-
Workbook
workbook
= excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
-
//创建压缩文件
-
String
nameByid
= baseMapper.getNameByid(viewid);
-
ZipEntry
zipEntry
=
new
ZipEntry(nameByid+
".xls");
-
zipOutputStream.putNextEntry(zipEntry);
-
//将excel对象以流的形式写入压缩流
-
workbook.write(zipOutputStream);
-
}
-
zipOutputStream.flush();
-
zipOutputStream.close();
-
}
3、设置下拉框的类:
-
package com.customization.BusinessFilIdExcel.utils;
-
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.hssf.usermodel.HSSFDataValidation;
-
import org.apache.poi.ss.usermodel.*;
-
import org.apache.poi.ss.util.CellRangeAddressList;
-
import java.util.List;
-
import java.util.Map;
-
public
class
SelectSheetWriteHandler
implements
SheetWriteHandler {
-
private Map
> selectMap;
-
private
int index;
-
private
char[] alphabet =
new
char[]{
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
-
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z'};
-
public
SelectSheetWriteHandler
(Map
> selectMap) {
-
this.selectMap = selectMap;
-
this.index =
0;
-
}
-
@Override
-
public
void
beforeSheetCreate
(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
-
}
-
@Override
-
public
void
afterSheetCreate
(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
-
if (selectMap ==
null || selectMap.size() ==
0) {
-
return;
-
}
-
// 需要设置下拉框的sheet页
-
Sheet
curSheet
= writeSheetHolder.getSheet();
-
DataValidationHelper
helper
= curSheet.getDataValidationHelper();
-
String
dictSheetName
=
"字典sheet";
-
Workbook
workbook
= writeWorkbookHolder.getWorkbook();
-
// 数据字典的sheet页
-
Sheet
dictSheet
= workbook.createSheet(dictSheetName);
-
// 从第二个工作簿开始隐藏,为了用户的友好性,将字典sheet隐藏掉
-
this.index++;
-
// 设置隐藏
-
workbook.setSheetHidden(
this.index,
true);
-
for (Map.Entry
> entry : selectMap.entrySet()) {
-
// 设置下拉单元格的首行、末行、首列、末列
-
CellRangeAddressList
rangeAddressList
=
new
CellRangeAddressList(
1,
65533, entry.getKey(), entry.getKey());
-
int
rowLen
= entry.getValue().size();
-
// 设置字典sheet页的值 每一列一个字典项
-
for (
int
i
=
0; i < rowLen; i++) {
-
Row
row
= dictSheet.getRow(i);
-
if (row ==
null) {
-
row = dictSheet.createRow(i);
-
}
-
row.createCell(entry.getKey()).setCellValue(entry.getValue().get(i));
-
}
-
String
excelColumn
= getExcelColumn(entry.getKey());
-
// 下拉框数据来源 eg:字典sheet!$B1:$B2
-
String
refers
= dictSheetName +
"!$" + excelColumn +
"$1:$" + excelColumn +
"$" + rowLen;
-
// 创建可被其他单元格引用的名称
-
Name
name
= workbook.createName();
-
// 设置名称的名字
-
name.setNameName(
"dict" + entry.getKey());
-
// 设置公式
-
name.setRefersToFormula(refers);
-
// 设置引用约束
-
DataValidationConstraint
constraint
= helper.createFormulaListConstraint(
"dict" + entry.getKey());
-
// 设置约束
-
DataValidation
validation
= helper.createValidation(constraint, rangeAddressList);
-
if (validation
instanceof HSSFDataValidation) {
-
validation.setSuppressDropDownArrow(
false);
-
}
else {
-
validation.setSuppressDropDownArrow(
true);
-
validation.setShowErrorBox(
true);
-
}
-
// 阻止输入非下拉框的值
-
validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
-
validation.createErrorBox(
"提示",
"此值与单元格定义格式不一致!");
-
// 添加下拉框约束
-
writeSheetHolder.getSheet().addValidationData(validation);
-
}
-
}
-
/**
-
* 将数字列转化成为字母列
-
*
-
* @param num
-
* @return
-
*/
-
private String
getExcelColumn
(int num) {
-
String
column
=
"";
-
int
len
= alphabet.length -
1;
-
int
first
= num / len;
-
int
second
= num % len;
-
if (num <= len) {
-
column = alphabet[num] +
"";
-
}
else {
-
column = alphabet[first -
1] +
"";
-
if (second ==
0) {
-
column = column + alphabet[len] +
"";
-
}
else {
-
column = column + alphabet[second -
1] +
"";
-
}
-
}
-
return column;
-
}
-
}
4、效果如下:
来源:https://blog.csdn.net/rjkkaikai/article/details/123448047