/**
* 导出业务处理
* 1.创建返回的流,创建对excel表格操作的workbook工作空间
* 2.设置表格头
* 3.根据主表长度获取表格块数量
* 4.依次将表格块写入excel表格
* 5.返回流
*
* @param condition 导出的条件 允许没有条件
* @param responses
*/
@Override
public void exportExcel(String condition, HttpServletResponse responses) {
/**
* 1.先从主张表中拿需要往excel表格中写入多少块数据
* resultDict:SYS_DICT表数据
*/
List<Map<String, Object>> resultDict = null;
if (condition.isEmpty())
resultDict = mapper.selectDict();
else {
Map<String, Object> conditionMap = new HashMap<>();
conditionMap.put("condition", condition);
resultDict = mapper.searchs(conditionMap);
}
/**
* 2.把两张表中的数据写入到Excel表格内
* pathFile:在本地这个路径下生成一个文件 文件名:字典信息xml.xls
* new FileOutputStream(new File(pathFile)):创建文件写入流
* new HSSFWorkbook().createSheet(参数"可以没有"):一个队excel表格的操作空间 xls结尾的表格 然后获取表格的第x页
*/
try {
// String pathFile = "D:/yc/work/TestFile/字典信息xml.xls";
// File file = new File(pathFile);
String name = "字典信息";
OutputStream os = responses.getOutputStream();
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
/**
* 设置表格样式
* setColumnWidth(列下标,宽度):
* setDefaultRowHeight(short类型的列高度):
* setActive(true):自动换行
* workbook.createCellStyle():获取CellStyle 设置字体的格式:左居中或者 居中等
* setWrapText(true):单元格内自动换行
* CellRangeAddress callRangeAddress0 = new CellRangeAddress(0, 1, 0, 0);//起始行,结束行,起始列,结束列::设置单元格合并条件
* sheet.addMergedRegion(callRangeAddress0);:将设置的合并条件给表格
*/
sheet.setColumnWidth(0, 5000);
sheet.setColumnWidth(1, 5000);
sheet.setColumnWidth(2, 7500);
sheet.setColumnWidth(3, 5000);
sheet.setColumnWidth(4, 5000);
sheet.setColumnWidth(5, 5000);
sheet.setColumnWidth(6, 7500);
sheet.setColumnWidth(7, 3000);
sheet.setDefaultRowHeight((short) 400);//列高
// sheet.setActive(true);//自动换行
CellStyle styleTitle = workbook.createCellStyle();
styleTitle.setBorderTop(BorderStyle.THIN);//上边框
styleTitle.setBorderBottom(BorderStyle.THIN);//下
styleTitle.setBorderLeft(BorderStyle.THIN);//左
styleTitle.setBorderRight(BorderStyle.THIN);//右
styleTitle.setAlignment(HorizontalAlignment.CENTER); //水平居中
styleTitle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
styleTitle.setWrapText(true);
sheet.createFreezePane(0, 2, 0, 2);
CellRangeAddress callRangeAddress0 = new CellRangeAddress(0, 1, 0, 0);//起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress1 = new CellRangeAddress(0, 1, 1, 1);//起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress2 = new CellRangeAddress(0, 1, 2, 2);//起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress3 = new CellRangeAddress(0, 1, 3, 3);//起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress4 = new CellRangeAddress(0, 0, 4, 7);//起始行,结束行,起始列,结束列
sheet.addMergedRegion(callRangeAddress0);
sheet.addMergedRegion(callRangeAddress1);
sheet.addMergedRegion(callRangeAddress2);
sheet.addMergedRegion(callRangeAddress3);
sheet.addMergedRegion(callRangeAddress4);
/**
* 表格标题头操作
* 标题头有点特殊
* sheet.createRow(i).createCell(0).setCellValue("test"):循环获取行,再给每一列赋值
*/
for (int i = 0; i < 2; i++) {
Row row = sheet.createRow(i);//获取这一行表格
if (i == 0) {
row.createCell(0).setCellValue("字典名称");
row.createCell(1).setCellValue("字典编码");
row.createCell(2).setCellValue("描述");
row.createCell(3).setCellValue("系统");
row.createCell(4).setCellValue("字典列表");
}
if (i == 1) {
row.createCell(4).setCellValue("字典项文本");
row.createCell(5).setCellValue("字典项值");
row.createCell(6).setCellValue("描述");
row.createCell(7).setCellValue("排序");
}
}
/**
* 表格内容操作
* 根据主表对表格块进行写入
* dictROw:初始化至表格开始的行,并根据表格快记录具体到表格哪一行 用来循环表格快
* dictRows:初始化至表格开始的行,并根据表格快记录具体到表格哪一行 用来获取这行表格
* dictValue:初始化值为0,表格快数据的下表,记录表格块数据到了这一块的那一行//记录这个主表对应的一块表格第几行 从0开始
* spaceLine:初始化值为0,每一块结束后都初始化为0 这一块数据的第几条数据 第一条需要对做三列表格进行写入 ,其余做三列表格不需要写入
*
* 循环主表 主表右多少条数据 就循环多少次 也就是多少块
* resultDict.size():主表长度 主表有多少条数据 表格就有多少块
* 获取第一块主表的id,根据id从数据库里面查询这一表格块右多少条数据
* 吧表格快的长度 当成内循环结束的条件 用dictRow记录
*/
int dictRow = 2;
int dictRows = 2;
int dictValue = 0;
int spaceLine = 0;
for (int k = 0; k < resultDict.size(); k++) {//
Map<String, Object> mapDict = resultDict.get(k);
List<Map<String, Object>> rows = mapper.searchRows(mapDict);
int rowSize = rows.size();//表格快长度
dictRow += rowSize;
/**
* 循环表格块
* dictRow:这一块表格结束后到了表格哪一行
* dictRows:表格在哪一行
* sheet.createRow(dictRows):获取这一行表格 获取完之后 dictRows++
* String[] stringRow:string数组 长度是表格的列长度 讲获取的块内所有数据 取出来放到数组对应的下表中
*/
for (; dictRows < dictRow; ) {
Row row = sheet.createRow(dictRows);
Map<String, Object> mapRowValue = rows.get(dictValue);
// if (dictValue == rows.size())
// dictValue = 0;
String[] stringRow = new String[8];
stringRow[0] = (String) mapRowValue.get("name");
stringRow[1] = (String) mapRowValue.get("code");
stringRow[2] = (String) mapRowValue.get("desc");
stringRow[3] = (String) mapRowValue.get("system");
stringRow[4] = (String) mapRowValue.get("itemValue");
stringRow[5] = (String) mapRowValue.get("itemNclob");
stringRow[6] = (String) mapRowValue.get("description");
stringRow[7] = (String) mapRowValue.get("sortOrder");
/**
* 循环给这一行表格进行写入
* 判断这表格快是否是多行
* spaceLines:表示列开始的下表 初始值为0
* dictValue
* 原来:这一块到哪一行了
* 现在:新增 如果不是这一块的第一行数据 哪spaceLines=3
* createCell(j).setCellValue(stringRow[j]):这一行的第几列写入数组中的那个数据
*/
int spaceLines = 0;
if (dictValue != 0) {
spaceLines = 4;
}
for (int j = spaceLines; j < 8; j++) {
row.createCell(j).setCellValue(stringRow[j]);
}
// spaceLine++;
dictRows++;
dictValue++;
if (dictValue == rowSize) {
dictValue = 0;
}
}
}
/**
* 将工作空间的内容写入流中
* workbook.write(os):数据写入流
* os.flush();:关闭流
* os.close();:关闭文件
*/
name = new String(name.getBytes("UTF-8"), "iso-8859-1");
responses.setCharacterEncoding("utf-8");
responses.setContentType("application/octet-stream;charset=utf-8");
responses.addHeader("Content-Disposition", "attachment;fileName=" + name + ".xlsx");
// OutputStream output = responses.getOutputStream();
workbook.write(os);
// os.flush();
// os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
导出Excel
于 2021-12-15 17:32:36 首次发布