Jxls+Spring MVC实现Excel导出

来源:互联网 发布:软件服务器的作用 编辑:程序博客网 时间:2024/05/21 21:48

Excel导出功能是业务系统比较常见的功能,我们可以使用POI、Jexcel等来进行Excel的操作,然后再结合Spring MVC对两者的支持进行导出。但此方法的不足之处在于我们需要不厌其烦的进行Excel表格的操作。经过一番寻觅,发现了Jxls开源框架,使用模版生成导出文件。

初识Jxls

模版制作

如下为制作好的模版,【A1:D1】处的注解用来标识模版的边界,使用${}来标识我们需要填充的数据。【A4】处理的注解来用遍历一个集合,我们对集合的每个元素取名为item,每个元素的又可以使用${item.属性}来进行获取 
这里写图片描述

包依赖

我们使用Maven来进行包依赖管理

<dependency>    <groupId>org.jxls</groupId>    <artifactId>jxls</artifactId>    <version>2.2.7</version></dependency><dependency>    <groupId>org.jxls</groupId>    <artifactId>jxls-poi</artifactId>    <version>1.0.6</version></dependency><dependency>    <groupId>org.apache.poi</groupId>    <artifactId>poi</artifactId>    <version>3.13</version></dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

注意 
使用Maven的 maven-resources-plugin 插件管理 resources 时,Maven会对模版进行转码处理,因此需要对xls格式的文件进行过滤,使其不处理。

<build>    <plugins>        <plugin>            <groupId>org.apache.maven.plugins</groupId>            <artifactId>maven-resources-plugin</artifactId>            <version>2.6</version>            <configuration>                <nonFilteredFileExtensions>                    <nonFilteredFileExtension>pdf</nonFilteredFileExtension>                    <nonFilteredFileExtension>swf</nonFilteredFileExtension>                    <nonFilteredFileExtension>data</nonFilteredFileExtension>                    <nonFilteredFileExtension>xls</nonFilteredFileExtension>                </nonFilteredFileExtensions>            </configuration>        </plugin>    </plugins></build>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

数据填充

try (InputStream is = Demo.class.getClassLoader().getResourceAsStream("template.xls")) {    try (OutputStream os = new FileOutputStream("output.xls")) {        Context context = new Context();        context.putVar("report_year", 2015);        context.putVar("report_month", 8);        //queryUser()为数据获取的方法        List<User> userList = queryUser();        context.putVar("users", userList);        JxlsHelper.getInstance().processTemplate(is, os, context);    } catch (IOException e) {        e.printStackTrace();    }} catch (IOException e) {    e.printStackTrace();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

效果展示

这里写图片描述

与Spring MVC结合

Spring提供了 AbstractExcelView 对提供对Excel导出的支持,继承该类的子类仅需要做Excel的处理。我们来看看Spring官网为我们提供的一个示例:

package excel;// imports omitted for brevitypublic class HomePage extends AbstractExcelView {    protected void buildExcelDocument(Map model,             HSSFWorkbook wb, HttpServletRequest req,            HttpServletResponse resp) throws Exception {        HSSFSheet sheet;        HSSFRow sheetRow;        HSSFCell cell;        // Go to the first sheet        // getSheetAt: only if wb is created from an existing document        // sheet = wb.getSheetAt(0);        sheet = wb.createSheet("Spring");        sheet.setDefaultColumnWidth((short) 12);        // write a text at A1        cell = getCell(sheet, 0, 0);        setText(cell, "Spring-Excel test");        List words = (List) model.get("wordList");        for (int i=0; i < words.size(); i++) {            cell = getCell(sheet, 2+i, 0);            setText(cell, (String) words.get(i));        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

我们可以看到上面的例子中,我们需要对Excel进行一个个单元格的数据填充,这是一项很烦锁的工作。现在让我们来看下,Jxls与Spring MVC的结合如何优雅的完成Excel的导出。我们依旧使用上面所述的模版。

编写View

我们继承Spring提供的 AbstractView 抽象类。

import org.jxls.common.Context;import org.jxls.util.JxlsHelper;import org.springframework.web.servlet.view.AbstractView;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.Map;public class JxlsExcelView extends AbstractView {    private static final String CONTENT_TYPE = "application/vnd.ms-excel";    private String templatePath;    private String exportFileName;    /**     * @param templatePath   模版相对于当前classpath路径     * @param exportFileName 导出文件名     */    public JxlsExcelView(String templatePath, String exportFileName) {        this.templatePath = templatePath;        if (exportFileName != null) {            try {                exportFileName = URLEncoder.encode(exportFileName, "UTF-8");            } catch (UnsupportedEncodingException e) {                e.printStackTrace();            }        }        this.exportFileName = exportFileName;        setContentType(CONTENT_TYPE);    }    @Override    protected void renderMergedOutputModel(            Map<String, Object> model,            HttpServletRequest request,            HttpServletResponse response) throws Exception {        Context context = new Context(model);        response.setContentType(getContentType());        response.setHeader("content-disposition",                "attachment;filename=" + exportFileName + ".xls");        ServletOutputStream os = response.getOutputStream();        InputStream is = getClass().getClassLoader().getResourceAsStream(templatePath);        JxlsHelper.getInstance().processTemplate(is, os, context);        is.close();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

请求处理

@RequestMapping(value = "/test")public ModelAndView export() {    Map<String, Object> model = new HashMap<>();    model.put("report_year", 2015);    model.put("report_month", 8);    //queryUser()为数据获取的方法    List<User> userList = queryUser();    model.put("users", userList);    return new ModelAndView(new JxlsExcelView("template.xls","output"), model);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

至此一个完整的Excel导出功能完成。是不是相当的简单及清晰?

相关及其它

其它支持

  • 支持 jx:if 语法
  • 支持Excel 公式
  • Jxls同时还提供了对Excel读取封装

以下为本人遇到过的问题,而本人实际使用的模版又较为复杂,有些问题需要跟踪代码来解决,因为错误提示有时不够友好。

  • 数据没办法解析,编写模版时要格外仔细
  • 数据遍历时Shift Row的格式问题
  • 数据遍历时,集合为空问题
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 富贵竹根部腐烂发臭怎么办 富贵竹根部发粘怎么办 水竹草叶子发黄怎么办 水竹叶子心发黄怎么办 塔竹叶子发黄怎么办 铁树叶有发黄怎么办 铁树夏天叶发黄怎么办 铁树的叶尖发黄怎么办 铁树叶子发黄是怎么办 榕树盆景长蜜怎么办 六月雪叶子枯萎了怎么办 小叶冬青掉叶子怎么办 榕树叶子发黄落叶怎么办 榕树的叶子发黄怎么办 盆景的叶子发黄怎么办 盆景叶子枯了怎么办 迎春盆景掉叶子怎么办 花叶子边缘干枯怎么办 刺梅的叶子发黄怎么办 榕树叶子发黑落叶怎么办 榕树树叶黄落叶怎么办 铜钱草叶子黄了怎么办 三角梅的叶子发黄怎么办 铜钱草水养叶子发黄怎么办 罗汉松叶片干了怎么办 三角梅叶子发甘怎么办 三角梅叶子蔫了怎么办 土培的绿萝烂根怎么办 水竹叶子变黄怎么办 富贵竹叶子蔫了怎么办 绿萝叶尖干枯怎么办 水竹叶干裂了怎么办 金钱草叶子蔫了怎么办 金钱草叶子太密怎么办 庭院竹子杆发黄怎么办 水竹长根了怎么办 富贵竹生虫子了怎么办 富贵竹张根了怎么办 盆栽树叶子发黄怎么办 水培转运竹杆发黄了怎么办 文竹叶子小虫子怎么办