码迷,mamicode.com
首页 > 其他好文 > 详细

poi导出excel下拉框联动--示例:学年学期

时间:2021-03-02 11:52:53      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:head   识别   边界值   star   api   ast   代码   erro   eva   

/**
* 导出课程excel
*
* @return
*/
@AutoLog(value = "课程-导出课程excel")
@ApiOperation(value = "课程-导出课程excel", notes = "导出课程excel")
@GetMapping(value = "/export/courseExcel")
public void export(HttpServletResponse res) throws Exception {
// 创建一个excel
@SuppressWarnings("resource")
XSSFWorkbook book = new XSSFWorkbook();

// 创建需要用户填写的sheet
XSSFSheet sheetPro = (XSSFSheet) book.createSheet("课程导入模板");
Row row0 = sheetPro.createRow(0);

//设置单元格宽
sheetPro.setColumnWidth(0,256*15);
sheetPro.setColumnWidth(1,256*20);
sheetPro.setColumnWidth(2,256*20);
sheetPro.setColumnWidth(3,256*15);
sheetPro.setColumnWidth(4,256*15);
sheetPro.setColumnWidth(5,256*15);
sheetPro.setColumnWidth(6,256*15);
sheetPro.setColumnWidth(7,256*15);
sheetPro.setColumnWidth(8,256*15);
sheetPro.setColumnWidth(9,256*15);

CellStyle style = CatalogExcelUtil.getHeadStyle(book);
     
     //设置第一行标题
CatalogExcelUtil.initCell(row0.createCell(0), style, "编号");
CatalogExcelUtil.initCell(row0.createCell(1), style, "课程代码");
CatalogExcelUtil.initCell(row0.createCell(2), style, "全称");
CatalogExcelUtil.initCell(row0.createCell(3), style, "英文名称");
CatalogExcelUtil.initCell(row0.createCell(4), style, "学分");
CatalogExcelUtil.initCell(row0.createCell(5), style, "学时");
CatalogExcelUtil.initCell(row0.createCell(6), style, "学年");
CatalogExcelUtil.initCell(row0.createCell(7), style, "学期");
CatalogExcelUtil.initCell(row0.createCell(8), style, "状态");
CatalogExcelUtil.initCell(row0.createCell(9), style, "开课来源");

//得到学年名称,放在列表里
List<SchoolYear> schoolYearList = schoolYearService.list();

ArrayList<String> schoolYearSelectList = new ArrayList<>();
for(int i=0; i < schoolYearList.size(); i++){
String schoolYearName = schoolYearList.get(i).getName().replace(‘~‘,‘_‘);
schoolYearSelectList.add("学年_"+schoolYearName);
}
//设置学年
String[] yearList = new String[schoolYearSelectList.size()];
schoolYearSelectList.toArray(yearList);

//将有子区域的父区域放到一个数组中
String[] areaFatherNameArr1 = yearList;
Map<String,String[]> schoolYearMap = new HashMap<String, String[]>();

for(SchoolYear sysDepart : schoolYearList){
List<Semester> semesterList = semesterService.list(Wrappers.<Semester>query().lambda().eq(Semester::getSchoolYearId, sysDepart.getId()));
ArrayList<String> semesterSelectList = new ArrayList<>();
for(int i=0; i < semesterList.size(); i++){
semesterSelectList.add(semesterList.get(i).getName());
}
//设置专业
String[] semesters = new String[semesterSelectList.size()];
semesterSelectList.toArray(semesters);
String schoolYearName = sysDepart.getName().replace(‘~‘,‘_‘); //将学年名称中的~替换成_(poi导出联动中,~和-符号无法识别,无法进行联动)
schoolYearMap.put("学年_"+schoolYearName, semesters); //设置父级对应的子级,下拉框联动父级不能以数字来头,必须为字母或者_符号
}

//创建一个专门用来存放学院专业信息的隐藏sheet页
//因此也不能在现实页之前创建,否则无法隐藏。
Sheet hideSheet1 = book.createSheet("area1");
//这一行作用是将此sheet隐藏,功能未完成时注释此行,可以查看隐藏sheet中信息是否正确
book.setSheetHidden(book.getSheetIndex(hideSheet1), true);

int rowId1 = 0;
// 设置第一行,存学院的信息
Row provinceRow1 = hideSheet1.createRow(rowId1++);
provinceRow1.createCell(0).setCellValue("学年学期");
for(int i = 0; i < yearList.length; i ++){
Cell provinceCell = provinceRow1.createCell(i + 1);
provinceCell.setCellValue(yearList[i]);
}
// 将具体的数据写入到每一行中,行开头为父级区域,后面是子区域。
for(int i = 0;i < areaFatherNameArr1.length;i++){
String key = areaFatherNameArr1[i];
String[] son = schoolYearMap.get(key);
Row row = hideSheet1.createRow(rowId1++);
row.createCell(0).setCellValue(key);
for(int j = 0; j < son.length; j ++){
Cell cell = row.createCell(j + 1);
cell.setCellValue(son[j]);
}

// 添加名称管理器
String range = getRange(1, rowId1, son.length);
Name name = book.createName();
//key不可重复
name.setNameName(key);
String formula = "area1!" + range;
name.setRefersToFormula(formula);
}

XSSFDataValidationHelper dvHelper1 = new XSSFDataValidationHelper((XSSFSheet)sheetPro);
// 学院规则
DataValidationConstraint provConstraint1 = dvHelper1.createExplicitListConstraint(yearList);
// 四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList provRangeAddressList1 = new CellRangeAddressList(1, 2000, 8, 8);
DataValidation provinceDataValidation1 = dvHelper1.createValidation(provConstraint1, provRangeAddressList1);
//验证
provinceDataValidation1.createErrorBox("error", "请选择正确的学年");
provinceDataValidation1.setShowErrorBox(true);
provinceDataValidation1.setSuppressDropDownArrow(true);
sheetPro.addValidationData(provinceDataValidation1);

//对前2000行设置有效性,G为学年对应的列,学期对应的为第8列
for(int i = 2;i < 2000;i++){
setDataValidation("G" ,sheetPro,i,8);
}

//设置状态
String[] statusCourse = new String[]{"开课", "未开课"};
DataValidation dataValidationStatusCourse = dropDownList(book, sheetPro, statusCourse, 1, 2000, 10, 10, "statusCourse", 3);

// 作用在目标sheet上
sheetPro.addValidationData(dataValidationStatusCourse);
// 设置hiddenSheet隐藏
// workbook.setSheetHidden(1, true);
// workbook.setSheetHidden(2, true);

// 第二行
Row row2 = sheetPro.createRow(1);
row2.setHeightInPoints(20);

CatalogExcelUtil.initCell(row2.createCell(0), style, "1");
CatalogExcelUtil.initCell(row2.createCell(1), style, "test123456");
CatalogExcelUtil.initCell(row2.createCell(2), style, "测试课程");
CatalogExcelUtil.initCell(row2.createCell(3), style, "testCourse");
CatalogExcelUtil.initCell(row2.createCell(4), style, "3");
CatalogExcelUtil.initCell(row2.createCell(5), style, "64");
CatalogExcelUtil.initCell(row2.createCell(6), style, "2016-2017");
CatalogExcelUtil.initCell(row2.createCell(7), style, "第一学期");
CatalogExcelUtil.initCell(row2.createCell(8), style, "开课");
CatalogExcelUtil.initCell(row2.createCell(9), style, "线下");

//
//将excel的数据写入文件
ByteArrayOutputStream fos = null;
byte[] retArr = null;
try {
fos = new ByteArrayOutputStream();
book.write(fos);
retArr = fos.toByteArray();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
OutputStream os = res.getOutputStream();
try {
String fileName = "课程模板.xlsx";//创建文件名
fileName = URLEncoder.encode(fileName, "UTF-8");
res.reset();
res.setHeader("Content-disposition", "attachment;filename=" + fileName);
// res.setHeader("Content-Disposition", "attachment; filename=课程模板.xls");//要保存的文件名
res.setContentType("application/octet-stream; charset=utf-8");
os.write(retArr);
os.flush();
} finally {
if (os != null) {
os.close();
}
}

}
/**
* 设置有效性
* @param offset 主影响单元格所在列,即此单元格由哪个单元格影响联动
* @param sheet
* @param rowNum 行数
* @param colNum 列数
*/
public static void setDataValidation(String offset,XSSFSheet sheet, int rowNum,int colNum) {
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
DataValidation data_validation_list;
data_validation_list = getDataValidationByFormula(
"INDIRECT($" + offset + (rowNum) + ")", rowNum, colNum,dvHelper);
sheet.addValidationData(data_validation_list);
}
/**
* 加载下拉列表内容
* @param formulaString
* @param naturalRowIndex
* @param naturalColumnIndex
* @param dvHelper
* @return
*/
private static DataValidation getDataValidationByFormula(
String formulaString, int naturalRowIndex, int naturalColumnIndex,XSSFDataValidationHelper dvHelper) {
// 加载下拉列表内容
// 举例:若formulaString = "INDIRECT($A$2)" 表示规则数据会从名称管理器中获取key与单元格 A2 值相同的数据,
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint(formulaString);
// 设置数据有效性加载在哪个单元格上。
// 四个参数分别是:起始行、终止行、起始列、终止列
int firstRow = naturalRowIndex -1;
int lastRow = naturalRowIndex - 1;
int firstCol = naturalColumnIndex - 1;
int lastCol = naturalColumnIndex - 1;
CellRangeAddressList regions = new CellRangeAddressList(firstRow,
lastRow, firstCol, lastCol);
// 数据有效性对象
// 绑定
XSSFDataValidation data_validation_list = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, regions);
data_validation_list.setEmptyCellAllowed(false);
if (data_validation_list instanceof XSSFDataValidation) {
data_validation_list.setSuppressDropDownArrow(true);
data_validation_list.setShowErrorBox(true);
} else {
data_validation_list.setSuppressDropDownArrow(false);
}
// 设置输入信息提示信息
data_validation_list.createPromptBox("下拉选择提示", "请使用下拉方式选择合适的值!");
// 设置输入错误提示信息
//data_validation_list.createErrorBox("选择错误提示", "你输入的值未在备选列表中,请下拉选择合适的值!");
return data_validation_list;
}

private String getRange(int offset, int rowId, int colCount) {
char start = (char)(‘A‘ + offset);
if (colCount <= 25) {
char end = (char)(start + colCount - 1);
return "$" + start + "$" + rowId + ":$" + end + "$" + rowId;
} else {
char endPrefix = ‘A‘;
char endSuffix = ‘A‘;
if ((colCount - 25) / 26 == 0 || colCount == 51) {// 26-51之间,包括边界(仅两次字母表计算)
if ((colCount - 25) % 26 == 0) {// 边界值
endSuffix = (char)(‘A‘ + 25);
} else {
endSuffix = (char)(‘A‘ + (colCount - 25) % 26 - 1);
}
} else {// 51以上
if ((colCount - 25) % 26 == 0) {
endSuffix = (char)(‘A‘ + 25);
endPrefix = (char)(endPrefix + (colCount - 25) / 26 - 1);
} else {
endSuffix = (char)(‘A‘ + (colCount - 25) % 26 - 1);
endPrefix = (char)(endPrefix + (colCount - 25) / 26);
}
}
return "$" + start + "$" + rowId + ":$" + endPrefix + endSuffix + "$" + rowId;
}
}


public static DataValidation dropDownList(XSSFWorkbook wb, XSSFSheet sheet, String[] datas, int startRow, int endRow,
int startCol, int endCol, String hidden, int num)
throws Exception{

XSSFWorkbook workbook = (XSSFWorkbook) wb;
Sheet hideSheet1 = workbook.createSheet(hidden);

for (int i = 0; i < datas.length; i++) {
hideSheet1.createRow(i).createCell(0).setCellValue(datas[i]);
}

// 创建名称,可被其他单元格引用
Name categoryName = workbook.createName();
categoryName.setNameName(hidden);
categoryName.setRefersToFormula(hidden + "!$A$1:$A$" + datas.length);
DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createFormulaListConstraint(hidden);

// 设置下拉框位置
CellRangeAddressList addressList = new CellRangeAddressList(startRow, endRow, startCol, endCol);
DataValidation dataValidation = helper.createValidation(constraint, addressList);
// 处理Excel兼容性问题
if (dataValidation instanceof XSSFDataValidation) {
// 数据校验
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
} else {
dataValidation.setSuppressDropDownArrow(false);
}
//隐藏工作表,num为传进来的第几个,0开始
workbook.setSheetHidden(num, true);
return dataValidation;
}


poi导出excel下拉框联动--示例:学年学期

标签:head   识别   边界值   star   api   ast   代码   erro   eva   

原文地址:https://www.cnblogs.com/jlov/p/14462164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!