页面导出Excel文件总结


1 概述:

1.1 导出耗时环节

1、利用MySQL语句查询行号,作为导出表格的序号


2、查询数据按照船代分组,Java代码获取分组数据


3、导出Excel文件按照船代分sheet页


4、导出设置错行号,导致表格标题丢失


5、设置导出表格样式



1.2 导出难点:

1、查询数据按照船代分组,Java代码获取分组数据


2、导出Excel文件按照船代分sheet页


2 利用MySQL语句查询行号,作为导出表格的序号


      将数据库查询数据导出到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,没有想到用其他的方法也可以实现(钻到牛角尖了)



启示:解决问题的方法不是唯一的,要学会举一反三







3 查询数据按照船代分组,Java代码获取分组数据


   查询的结果是:



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);
}
}



4 导出Excel文件按照船代分sheet页


    导出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集合



5 导出设置错行号,导致表格标题丢失



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不太熟悉,要不断尝试,挺浪费时间的!