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

  • 相关阅读:
    评七种武器之碧玉刀
    EFCore join table and AutoMapper
    虚拟网络的简单知识总结
    kubernetes中不可见的OOM
    神通数据库安装配置方法
    OpenEuler2203安装Redislabs的简单记录
    Redislabs的简单使用与benchmark测试结果
    springMVC捕获404错误并统一返回json格式 规格严格
    zeromq简介及各个通讯模式实例详解(附java实现) 规格严格
    记录java.lang.NoClassDefFoundError: org/springframework/boot/logging/DeferredLogFactory错误 规格严格
  • 原文地址:https://www.cnblogs.com/zhangchengbing/p/9835083.html
Copyright © 2020-2023  润新知