页面导出Excel文件总结
1.1 导出耗时环节
1、利用MySQL语句查询行号,作为导出表格的序号
2、查询数据按照船代分组,Java代码获取分组数据
3、导出Excel文件按照船代分sheet页
4、导出设置错行号,导致表格标题丢失
5、设置导出表格样式
1.2 导出难点:
1、查询数据按照船代分组,Java代码获取分组数据
2、导出Excel文件按照船代分sheet页
将数据库查询数据导出到Excel文件,Excel文件里有一列是序号,一般情况下,序号可以用数据库表行号代替。但是,我这次用的是MySQL数据库,想直接利用自带的函数查询行号,却不能实现
查找网上资料,发现大多是写两个函数,一个是:
DELIMITER $$
USE `aop`$$
DROP FUNCTION IF EXISTS `rownums`$$
CREATE DEFINER=`root`@`%` FUNCTION `rownums`() RETURNS INT(11)
BEGIN
SET @rownum = @rownum + 1;
RETURN @rownum;
END$$
DELIMITER ;
另一个是:
DELIMITER $$
USE `aop`$$
DROP FUNCTION IF EXISTS `rownums_reset`$$
CREATE DEFINER=`root`@`%` FUNCTION `rownums_reset`() RETURNS INT(11)
BEGIN
SET @rownum = 0;
RETURN 1;
END$$
DELIMITER ;
利用两个查询行号,select rownums(),sa from t where rownums_reset() = 1;
还有一种方法是:
SELECT
(@rowNum := @rowNum + 1) AS rownum
FROM
t_stu_info,
(SELECT
(@rowNum := 0)) b
ORDER BY t_stu_info.age DESC
但是,实际上这里可以不利用SQL里的行号,可以用查询的结果数作为行号
for(int i = 0 ; i<data.size();i++)
{
Map<String,Object> map=(Map<String, Object>) data.get(i);
HSSFRow datarow = sheet.createRow(i+1);
HSSFCell cell0 = datarow.createCell(0);
HSSFRichTextString t0 = new HSSFRichTextString((i+1)+"");
cell0.setCellValue(t0);
}
这一步由于太依靠SQL,没有想到用其他的方法也可以实现(钻到牛角尖了)
启示:解决问题的方法不是唯一的,要学会举一反三
查询的结果是:
A B C D
A B1 F G
A H I L
B C D T L
B R U E T
B W Q S I
C E K C V
C X T O P
根据查询结果,将数据以第一列分组放在List集合里,分成三组
A B C D
A B1 F G
A H I L
B C D T L
B R U E T
B W Q S I
C E K C V
C X T O P
分别循环三个List,生成三个sheet页
List<List<Map<String,Object>>> itemList = new ArrayList<List<Map<String,Object>>>();
List<Object> data=msg.getData();
String aa = “-1”;
for(int i=0;i<data.size();i++)
{
Map<String,Object> map=(Map<String, Object>) data.get(i);
String a= map.get("A").toString();
Map<String,Object> item = new HashMap<String, Object>();
item.put("A", map.get("A"));
item.put("B", map.get("B"));
item.put("C", map.get("C"));
item.put("D", map.get("D"));
item.put("E", map.get("E"));
if(!aa.equals(a))
{
aa=a;
List<Map<String,Object>> t=new ArrayList<Map<String, Object>>();
t.add(item);
itemList.add(t);
}
else
{
if(itemList.size() >= 1)
{
itemList.get(itemList.size()-1).add(item);
}
}
}
for(int j=0;j<itemList.size();j++)
{
for(int i = 0 ; i<itemList.get(j).size();i++)
{
Map<String,Object> map=(Map<String, Object>) itemList.get(j).get(i);
}
}
导出Excel文件中按照船代进行分sheet页
HSSFWorkbook workbook = new HSSFWorkbook();
for(int j=0;j<itemList.size();j++)
{
HSSFSheet sheet = workbook.createSheet("清单"+j);
sheet.setDefaultColumnWidth((short) 15);
}
FileOutputStream stream = new FileOutputStream("d:/one.xls");
workbook.write(stream);
根据查询数据的数目来分sheet,应为之前是通过船代编码分组成多个list集合
HSSFRow rowHead = sheet.createRow(0);
// 设置行高
rowHead.setHeight((short) 400);
// 创建第一列
HSSFCell cellHead = rowHead.createCell(0);
cellHead.setCellValue(new HSSFRichTextString("清单"));
cellHead.setCellStyle(headStyle);
CellRangeAddress range = new CellRangeAddress(0, 0, 0, 11);
sheet.addMergedRegion(range);
HSSFRow rowTitle = sheet.createRow(1);
rowTitle.setHeight((short) 400);
HSSFCell cellTitle = rowTitle.createCell(0);
cellTitle.setCellValue(new HSSFRichTextString(str+":"));
cellTitle.setCellStyle(headTitle);
range = new CellRangeAddress(1, 1, 0, 11);
sheet.addMergedRegion(range);
// 产生表格标题行
HSSFRow row = sheet.createRow(1);
HSSFCell cell = row.createCell(0);
HSSFRichTextString text = new HSSFRichTextString("序号");
cell.setCellValue(text);
cell.setCellStyle(normalTitle);
由于标题创建行和表头创建行号一致,HSSFRow rowTitle = sheet.createRow(1); 重复设置第二行(从0开始),导致表头无法出现,这也浪费了很多时间
6 设置导出表格样式
HSSFFont tabFont = workbook.createFont();
tabFont.setFontName("微软雅黑");
tabFont.setFontHeightInPoints((short)10);
HSSFCellStyle tabTitle = workbook.createCellStyle();
tabTitle.setFont(tabFont);
tabTitle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
tabTitle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
tabTitle.setBorderRight((short) 1);
tabTitle.setBorderBottom((short) 1);
tabTitle.setBorderLeft((short) 1);
tabTitle.setBorderTop((short) 1);
由于对POI不太熟悉,要不断尝试,挺浪费时间的!