JavaWeb项目操作Excel(导出、解析)

对于javaweb开发者来说,对于Excel的操作是必须要了解的知识点,自己原先也做过一些excel的操作,但是没有系统的整理过,所以每回使用的时候都是在重新查找信息,所以做了如下整理:

其实在javaweb开发中经常用到的Excel操作便是导出、解析。下面就从这两个方面来总结。

首先便是导出,在这个方面其实我主要用到的是两种方式:一种是依赖于freemarker,另一种则是POI

一、依赖于freemarker的Excel导出:

首先如果要使用freemarker的导出方式,在框架中必须使用了freemarker这个模板引擎,对于现在主流的mvc框架来说:spring mvc是可以集成freemarker的,spring boot则更近一步,spring mvc推荐使用jsp,而spring boot 推荐使用freemarker。至于Struts2本人没有涉及过不是很清楚,需要自己去探索啊!!不过应该也是没有问题的。然后就是Struts这个东西,我想现在应该没有公司在用Struts了吧!!!

好!!闲话不多直接上操作步骤,我这里的代码是使用的spring boot+freemarker的方式,至于dao层本文档不会涉及其内容:

(一)、首先要做的便是将要导出的Excel的模板准备好,接编写一个Excel表格,如图:

 

(二)、将Excel另存为xml格式:

然后用文本编辑器打开Excel文件看到内容为:

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
 <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  <Created>2006-09-16T00:00:00Z</Created>
  <LastSaved>2018-10-22T03:45:04Z</LastSaved>
  <Version>15.00</Version>
 </DocumentProperties>
 <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  <AllowPNG/>
  <RemovePersonalInformation/>
 </OfficeDocumentSettings>
 <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
  <WindowHeight>8010</WindowHeight>
  <WindowWidth>14805</WindowWidth>
  <WindowTopX>240</WindowTopX>
  <WindowTopY>105</WindowTopY>
  <ProtectStructure>False</ProtectStructure>
  <ProtectWindows>False</ProtectWindows>
 </ExcelWorkbook>
 <Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Bottom"/>
   <Borders/>
   <Font ss:FontName="宋体" ss:Size="11" ss:Color="#000000"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
  <Style ss:ID="s16">
   <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
  </Style>
  <Style ss:ID="s17">
   <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
  </Style>
  <Style ss:ID="s18">
   <Alignment ss:Vertical="Center" ss:WrapText="1"/>
  </Style>
  <Style ss:ID="s19">
   <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
   <NumberFormat ss:Format="yyyy/m/d\ hh:mm:ss"/>
  </Style>
 </Styles>
 <Worksheet ss:Name="存储池">
  <Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="2" x:FullColumns="1"
   x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
   <Column ss:AutoFitWidth="0" ss:Width="123.75" ss:Span="3"/>
   <Row>
    <Cell ss:StyleID="s16"><Data ss:Type="String">存储池名</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="String">总容量(TB)</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="String">已使用容量(TB)</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="String">未使用容量(TB)</Data></Cell>
   </Row>
   <Row>
    <Cell ss:StyleID="s16"><Data ss:Type="String">pool0</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="Number">5.68</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="Number">1.23</Data></Cell>
    <Cell ss:StyleID="s17"><Data ss:Type="Number">2.33</Data></Cell>
   </Row>
  </Table>
  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <PageSetup>
    <Header x:Margin="0.3"/>
    <Footer x:Margin="0.3"/>
    <PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
   </PageSetup>
   <Print>
    <ValidPrinterInfo/>
    <PaperSizeIndex>9</PaperSizeIndex>
    <HorizontalResolution>600</HorizontalResolution>
    <VerticalResolution>600</VerticalResolution>
   </Print>
   <Selected/>
   <Panes>
    <Pane>
     <Number>3</Number>
     <ActiveCol>4</ActiveCol>
    </Pane>
   </Panes>
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>
 <Worksheet ss:Name="报错日志">
  <Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="2" x:FullColumns="1"
   x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
   <Column ss:AutoFitWidth="0" ss:Width="153"/>
   <Column ss:AutoFitWidth="0" ss:Width="81.75"/>
   <Column ss:AutoFitWidth="0" ss:Width="605.25"/>
   <Row ss:AutoFitHeight="0" ss:Height="20.0625">
    <Cell ss:StyleID="s16"><Data ss:Type="String">时间</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="String">级别</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="String">内容</Data></Cell>
   </Row>
   <Row ss:Height="27">
    <Cell ss:StyleID="s19"><Data ss:Type="String" x:Ticked="1">2017/12/12  11:11:11</Data></Cell>
    <Cell ss:StyleID="s16"><Data ss:Type="String">error</Data></Cell>
    <Cell ss:StyleID="s18"><Data ss:Type="String">fdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsasdfdsafsddddddddddddddddddddddddddfsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Data></Cell>
   </Row>
  </Table>
  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <PageSetup>
    <Header x:Margin="0.3"/>
    <Footer x:Margin="0.3"/>
    <PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
   </PageSetup>
   <Print>
    <ValidPrinterInfo/>
    <PaperSizeIndex>9</PaperSizeIndex>
    <HorizontalResolution>600</HorizontalResolution>
    <VerticalResolution>600</VerticalResolution>
   </Print>
   <Panes>
    <Pane>
     <Number>3</Number>
     <ActiveRow>1</ActiveRow>
    </Pane>
   </Panes>
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>
</Workbook>

(三)、接下来便是将xml代码复制到一个新建的freemarker模板文件中便可以了

(四)、下面便是java代码的编写了,废话不多直接上代码:

 1 @RequestMapping("/exportreport")
 2     private String exportReport(Model model,HttpServletRequest request,HttpServletResponse response,int did) {
 3         
 4         //获取要导入的信息
 5         List<DPool> poolList=reportService.selectPoolByDid(did);
 6         List<DAlarm> alarmList=reportService.selectAlarmByDid(did);
 7         Device device = deviceDao.selectByPrimaryKey(did);
 8         
 9         
10         //将需要到导入的信息存入model中
11         model.addAttribute("poolList", poolList);
12         model.addAttribute("alarmList", alarmList);
13         
14         
15         //设置下载头部,通过response实现
16         response.reset();
17         response.setContentType("application/vnd.ms-excel;charset=utf-8");
18         try {
19             response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(device.getName()+"-report.xls", "UTF8"));
20         } catch (UnsupportedEncodingException e) {
21             e.printStackTrace();
22         }
23         //带导出数据跳转到freemarker模板
24         return "generate_reports";
25     }

 (五)、最后便是利用freemarker的知识去编写,上面新建的模板了,将数据插入到模板中,其中有些地方需要注意一下:

  这个地方的数字代表了这张工作表中有多少行

二、第二种方式便是利用POI了,步骤如下:

  (一)、利用poi生成Excel表格

 1 package cn.tools;
 2 
 3 import java.text.DecimalFormat;
 4 import java.util.List;
 5 
 6 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 7 import org.apache.poi.hssf.usermodel.HSSFFont;
 8 import org.apache.poi.hssf.usermodel.HSSFRow;
 9 import org.apache.poi.hssf.usermodel.HSSFSheet;
10 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
11 import org.apache.poi.ss.usermodel.HorizontalAlignment;
12 import org.apache.poi.ss.usermodel.VerticalAlignment;
13 
14 import cn.entitys.DAlarm;
15 import cn.entitys.DPool;
16 
17 public class GenerateReport {
18     public static HSSFWorkbook Generate(List<DPool> poolList, List<DAlarm> alarmList){
19         HSSFWorkbook workbook = new HSSFWorkbook();
20         HSSFSheet firstsheet = workbook.createSheet("存储池");
21         
22         HSSFFont font = workbook.createFont();
23         font.setFontName("宋体");
24         font.setFontHeightInPoints((short) 11);
25         
26         HSSFCellStyle cellStyle1 = workbook.createCellStyle();
27         cellStyle1.setAlignment(HorizontalAlignment.CENTER);
28         cellStyle1.setVerticalAlignment(VerticalAlignment.CENTER);
29         cellStyle1.setFont(font);
30 
31         firstsheet.setColumnWidth(0, 20*265);
32         firstsheet.setColumnWidth(1, 20*265);
33         firstsheet.setColumnWidth(2, 20*265);
34         firstsheet.setColumnWidth(3, 20*265);
35         firstsheet.setDefaultColumnStyle(0, cellStyle1);
36         firstsheet.setDefaultColumnStyle(1, cellStyle1);
37         firstsheet.setDefaultColumnStyle(2, cellStyle1);
38         firstsheet.setDefaultColumnStyle(3, cellStyle1);
39 
40         HSSFRow row = firstsheet.createRow(0);
41         row.setHeight((short) (13.5*20));
42         row.createCell(0).setCellValue("存储池名");
43         row.createCell(1).setCellValue("总容量(TB)");
44         row.createCell(2).setCellValue("已使用容量(TB)");
45         row.createCell(3).setCellValue("未使用容量(TB)");
46         
47         double d = Math.random()*10;
48         DecimalFormat dFormat = new DecimalFormat("#.00");
49         for (int i=0;i<poolList.size();i++) {
50             DPool pool=poolList.get(i);
51             row = firstsheet.createRow(i+1);
52             row.setHeight((short) (13.5*20));
53             row.createCell(0).setCellValue(pool.getName());
54             row.createCell(1).setCellValue(pool.getCapacity());
55             row.createCell(2).setCellValue(pool.getUsed_capacity());
56             row.createCell(3).setCellValue(pool.getFree_capacity());
57         }
58         
59         HSSFSheet secondsheet = workbook.createSheet("报错日志");
60         
61         HSSFCellStyle cellStyle2 = workbook.createCellStyle();
62         cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
63         cellStyle2.setAlignment(HorizontalAlignment.LEFT);
64         cellStyle2.setFont(font);
65         cellStyle2.setWrapText(true);
66         
67         HSSFCellStyle cellStyle3 = workbook.createCellStyle();
68         cellStyle3.setAlignment(HorizontalAlignment.CENTER);
69         cellStyle3.setFont(font);
70         
71         secondsheet.setColumnWidth(0, 25*265);
72         secondsheet.setColumnWidth(1, 13*265);
73         secondsheet.setColumnWidth(2, 100*265);
74         secondsheet.setDefaultColumnStyle(0, cellStyle1);
75         secondsheet.setDefaultColumnStyle(1, cellStyle1);
76         secondsheet.setDefaultColumnStyle(2, cellStyle2);
77         
78         HSSFRow row2 = secondsheet.createRow(0);
79         row2.setHeight((short) (20*20));
80         row2.createCell(0).setCellValue("时间");
81         row2.createCell(1).setCellValue("级别");
82         row2.createCell(2).setCellValue("内容");
83         row2.getCell(2).setCellStyle(cellStyle3);
84         for(int i=0;i<alarmList.size();i++){
85             DAlarm alarm=alarmList.get(i);
86             row2 = secondsheet.createRow(i+1);
87             row2.setHeight((short) (27*20));
88             row2.createCell(0).setCellValue(alarm.getTime());
89             row2.createCell(1).setCellValue(alarm.getLevel());
90             row2.createCell(2).setCellValue(alarm.getContext());
91         }
92         return workbook;
93     }
94 }

 

      

  (二)、设置control中的下载头部,这里和freemarker的导出是一样的。

  (三)、利用输入输出流,输出到浏览器

 1 package cn.Controllers;
 2 
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 import java.io.UnsupportedEncodingException;
 6 import java.net.URLEncoder;
 7 import java.text.DecimalFormat;
 8 import java.util.List;
 9 
10 import javax.servlet.ServletOutputStream;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 
14 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
15 import org.apache.poi.hssf.usermodel.HSSFFont;
16 import org.apache.poi.hssf.usermodel.HSSFRow;
17 import org.apache.poi.hssf.usermodel.HSSFSheet;
18 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
19 import org.apache.poi.ss.usermodel.HorizontalAlignment;
20 import org.apache.poi.ss.usermodel.VerticalAlignment;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Controller;
23 import org.springframework.ui.Model;
24 import org.springframework.web.bind.annotation.RequestMapping;
25 import org.springframework.web.bind.annotation.ResponseBody;
26 
27 import cn.dao.DeviceMapper;
28 import cn.entitys.DAlarm;
29 import cn.entitys.DPool;
30 import cn.entitys.Device;
31 import cn.service.ReportService;
32 import cn.service.ThreadService;
33 import cn.tools.GenerateReport;
34 
35 @Controller
36 @RequestMapping("/report")
37 public class ReportController {
38     
39     @Autowired
40     ReportService reportService;
41     
42     @Autowired
43     ThreadService threadService;
44     
45     @Autowired
46     DeviceMapper deviceDao;
47     
48     @RequestMapping("/exportreport")
49     private void exportReport(Model model,HttpServletRequest request,HttpServletResponse response,int did) throws IOException {
50         
51         //获取要导入的信息
52         List<DPool> poolList=reportService.selectPoolByDid(did);
53         List<DAlarm> alarmList=reportService.selectAlarmByDid(did);
54         Device device = deviceDao.selectByPrimaryKey(did);
55         
56         
57         //生成Excel表
58         HSSFWorkbook workbook = GenerateReport.Generate(poolList, alarmList);
59         
60         
61         //设置下载头部,通过response实现
62         response.reset();
63         response.setContentType("application/vnd.ms-excel;charset=utf-8");
64         try {
65             response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(device.getName()+"-report.xls", "UTF8"));
66         } catch (UnsupportedEncodingException e) {
67             e.printStackTrace();
68         }
69         ServletOutputStream fileOut = response.getOutputStream();
70         workbook.write(fileOut); 
71     }
72     98 }

 

这里没有编写代码,后续会跟上的。

三、Excel的解析:

其实这一部分可以分为两部分来讲解 ,首先涉及到的便是文件的上传,毕竟有文件上传了才能进行解析,然后便是利用POI解析上传后的文件获取数据,

至于POI 的操作会在下一篇博客中整理。

 

posted @ 2018-10-23 10:14  秋心无波  阅读(5682)  评论(0编辑  收藏  举报