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 的操作會在下一篇博客中整理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM