一 前言
开发中,对于导出一个excel表格这样的功能很常见,这里谈谈我所知道的相关知识
二 需求
导出某个套餐所关联的所有项目的一个Excel表格
三 HSSFWorkbook
//创建一个Excel文件
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
//设置列宽 参数一:第几列,参数二:列宽(列宽有限制,会出现空指针)
sheet.setColumnWidth(0, 1000);
sheet.setColumnWidth(1, 1000);
sheet.setColumnWidth(2, 1000);
sheet.setColumnWidth(3, 1000);
//样式
//两个最基本的样式
HSSFCellWork sheetStyle = workbook.createCellStyle();
sheetStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
sheetStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
//其他比如颜色,边框样式就不例举了
try{
int rowNum = 0;
HSSFRow row = sheet.getRow(rowNum);
if(row == null) {
HSSFRow row = sheet.createRow(rowNum);
}
//第一行高度 相当于标题
row.setHeight((short)500);
//设置标题
row.setCellValue("套餐ID");
row.setCellValue("套餐名称");
row.setCellValue("。。。。");
//获取数据集 list
List<Object> list = XXXService.get(xxx);
//动态生成表格数据
if(list != null && list.size() > 0) {
for(Object item : list) {
row.setCellValue(item.getId);
row.setCellValue(item.getName);
row.setCellValue(item.getXXX);
rowNum++;
}
}
//接下来就是文件处理了 可能用到阿里云的东西,看你公司用的技术
}catch (Exception e) {
e.printStackTrace();
//返回给上层 用来判断是否成功
return "500";
}finally {
}
return "";
合并单元格
老版本
sheet.addMergedRegion(new Region((short)0,(short)i,(short)1,(short)i));
现在用
addMergedRegion(new CellRangeAddress(row,row,col,col);
参数一 第一个单元格所在行
参数二 第二个单元格所在行
参数三 第一个单元格所在列
参数死 第二个单元格所在列
其实对于固定行和列的合并很简单,复杂的是动态合并,行和宽都是不确定的,我以前没有好好想过这个问题,今天仔细想了想,功能还是实现了,很开心,我这里给个思路:
分析:首先你要将数据分组!!!!你要知道四个参数中,在同一个列下,有两个参数我们是知道的,就是两个col是知道的,问题关键是,前两个行数不确定,因为,第一个单元格行数,你不知道前面已有多少行,即使知道,你也不知道这组数据长度(我简称是跨度)。
好的问题已找到!说下我今天实现的思路!
首先,两个for循环找出重复的name(数据结构简单算法),对于重复数据,我们只放一个到map中,key是name,value是list,先放一个0进去,数据结构是Map<String,List<Integer>>
然后遍历list的时候,先判断,是否在map中,如果是,就记下每次出现的行数存到list中(好处后面你就知道),当然这里有一些细节。
遍历完后,数据都写到文件中了,这个时候单独进行合并。这个时候就知道map中list存的行数的重要性了!他们分别记录了,该组数据第一次出现的行数一直到最有一次出现的行数,写到这里,聪明的你可能已经想到明天接下来的代码了:list中第一个数据就是第一个单元格所在行数,list最后一个数据就是第二个单元格所在行数。。
代码:
//记录重复数据
for(int i = 0; i< itemList.size() - 1; i++) {
for(int j = itemList.size() - 1 ; j > i ; j--) {
if(itemList.get(i).getSummaryName().equals(itemList.get(j).getSummaryName())) {
List<Integer> innerList = map.get(itemList.get(i).getSummaryName());
if(innerList == null) {
List<Integer> list = new ArrayList<Integer>();
list.add(0);
map.put(itemList.get(i).getSummaryName(),list);
}
}
}
}
}
//记录所有有共同点数据的行数
for(String title : titleSet) {
row.createCell(0).setCellValue(title);
if(map.get(title) != null) {
List<Integer> listInner = map.get(title);
listInner.add(i);
map.put(title,listInner);
}
i++;
}
rowNum ++;
//根据map合并
for(Map.Entry<String, List<Integer>> entry : map.entrySet()) {
List<Integer> list = entry.getValue();
int firstRow = list.get(0);
int secondRow = list.get(list.size() - 1);
CellRangeAddress range = new CellRangeAddress(firstRow,secondRow,0,0);
sheet.addMergedRegion(range);
}
其实,我以前也是很怕遇到复杂的问题,后来慢慢觉得,怕也是解决不了问题的,躲掉这次,下次你怎么办?只有直面困难,勇往直前,才能使自己变强!