POI实现导出Excel

此例为maven项目,实现学生模块列表信息的导出Excel操作。所用框架为SSM框架。
工具类 ExportExcelUtil.java 中均为公用方法,无论任何框架项目都可直接调用类中方法,只需将对应的参数传到方法中即可。
1.jar包
在maven项目中增加如下配置即可。若非maven项目,将jar包下载后导入项目中。



  org.apache.poi
  poi
  3.16


  org.apache.poi
  poi-ooxml
  3.16

2.JSP
注意:类似于导出、下载的功能,均需要response实现输出,ajax不支持文件输出流,所以导出、下载功能均不能够利用ajax的方式实现。一般采取超链接或构造表单提交form实现。
在正常的业务中,一般规则为“所见及所得”,所以导出Excel时需要关联查询区域的查询条件进行导出,所以在此例中,利用基本的查询表单实现导出Excel的功能。

查询 重置 导出Excel

3.JS

/**
 * 页面初始化
 */
$(document).ready(function () {
  $("#exportExcelStudent").on("click",exportExcelStudent); //导出Excel按钮绑定事件
});
/**
 * 导出Excel
 * @returns
 */
function exportExcelStudent(){
  //定义URL为导出Excel的后台请求地址
  var url = "../file/demoStudentFile/exportExcel"; 
  //将URL加至form的action中
  $("#search-form").attr("action",url);
  //提交form表单
  $("#search-form").form('submit',{});
}

4.实体类 DemoStudent.java

package com.project.entity.demo;

import com.project.entity.BaseEntity;

/**
 * @author hmz 2017年12月25日 下午5:05:03 学生实体类
 */
@SuppressWarnings("serial")
public class DemoStudent extends BaseEntity {
    private String stuId;// 学生id
    private String name;// 学生姓名
    private String sex;// 学生性别
    private String phone;// 学生电话
    private String address;// 学生地址
    private String message;// 学生自我评价
    private String fkFileId;// 附件ID
    private String fkFileName;// 附件名称

    public String getStuId() {
        return stuId;
    }
    public void setStuId(String stuId) {
        this.stuId = stuId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getFkFileId() {
        return fkFileId;
    }
    public void setFkFileId(String fkFileId) {
        this.fkFileId = fkFileId;
    }
    public String getFkFileName() {
        return fkFileName;
    }
    public void setFkFileName(String fkFileName) {
        this.fkFileName = fkFileName;
    }
}

5.Controller层 DemoStudentFileController.java 主要用于获取前台参数并调用Service中方法

package com.project.controller.demo;

import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.project.entity.demo.DemoStudent;
import com.project.service.demo.DemoStudentService;
import com.project.util.cipher.CipherTransport;

/**
 * @ClassName: DemoStudentFileController
    * @Description: TODO
    * @author: HeMengZhu
 * @date: 2018年2月28日 下午3:49:22
 */
@Controller
@CipherTransport
@RequestMapping("/file/demoStudentFile")
public class DemoStudentFileController {
  @Autowired
  private DemoStudentService demoStudentService;

  /**
   * 导出Excel
   * @Title: exportExcel
   * @Description: TODO
   * @param param 查询参数
   * @param response
   * @throws IOException
   * @return: void
   */
  @ResponseBody
  @RequestMapping(value = "/exportExcel", method = RequestMethod.POST)
  public void exportExcel(DemoStudent stu, HttpServletResponse response) throws                                                                     IOException {
      demoStudentService.exportExcel(stu, response);
  }
}

6.Service层 DemoStudentService.java 主要处理业务逻辑并访问公用方法将数据写入Excel并导出

package com.project.service.demo;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.impl.util.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.project.entity.demo.DemoStudent;
import com.project.mapper.demo.DemoStudentMapper;
import com.project.util.ConstUtil;
import com.project.util.file.ExportExcelUtil;
import com.project.util.file.FileConstUtil;
import com.project.util.file.FileValidateUtil;
import com.project.util.file.ImportExcelUtil;

/**
 * @ClassName: DemoStudentService
 * @Description: TODO
 * @author: HeMengZhu
 * @date: 2018年2月28日 下午3:52:03
 */
@Service
public class DemoStudentService {
    @Autowired
    private DemoStudentMapper demoStudentMapper;
    @Autowired
    private DemoFileService demoFileService;
        
    /**
     * 导出表格
     * @Title: exportExcel
     * @Description: TODO
     * @param stu
     * @param response
     * @return
     * @throws IOException
     * @return: boolean
     */
    @Transactional
    public void exportExcel(DemoStudent stu, HttpServletResponse response) throws IOException {
        try {
            // 获取要导出的数据集合
            List list = demoStudentMapper.excelList(stu);
            // 组装数据格式
            List> tableList = new ArrayList<>();
            // 示例中只导出一个sheet页
            List tableList_1 = new ArrayList();
            int tableNum_1 = 1;
            for (DemoStudent demoStudent : list) {
                // 数组长度要与FileConstUtil.DemoStudentMessage.EXCEL_HEADER常量类中对应的各个sheet页的标题行长度一致,否则报空指针错误
                String[] s = new String[FileConstUtil.DemoStudentMessage.EXCEL_HEADER.get(0).length];
                s[0] = tableNum_1++ + "";
                s[1] = demoStudent.getName() == null ? "" : demoStudent.getName(); // 姓名
                s[2] = demoStudent.getSex() == null ? "" : demoStudent.getSex(); // 性别
                s[3] = demoStudent.getPhone() == null ? "" : demoStudent.getPhone(); // 电话
                tableList_1.add(s);
            }
            // 将第一个sheet页数据放在集合中
            tableList.add(tableList_1);
            // 调用导出Excel工具类
            ExportExcelUtil util = new ExportExcelUtil();
            util.exportExcelsUtil(FileConstUtil.DemoStudentMessage.EXCEL_NAME, FileConstUtil.DemoStudentMessage.EXCEL_SHEET_NAME, FileConstUtil.DemoStudentMessage.EXCEL_TITLE,
                    FileConstUtil.DemoStudentMessage.EXCEL_HEADER, tableList, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

7.Mapper层 DemoStudentMapper.java 接口,与XML文件相对应,实现对数据库的访问和操作

package com.project.mapper.demo;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import com.project.entity.demo.DemoStudent;

/**
 * @author hmz 2018年02月27日 下午8:01:00 示例-测试学生Mapper
 */
@Repository
public interface DemoStudentMapper {
    /**
     * 获取导出表格数据集合
     * @Title: excelList
     * @Description: TODO
     * @param stu
     * @return
     * @return: List
     */
    List excelList(DemoStudent stu);
}

8.Mapper层 DemoStudentMapper.xml 主要包含数据库字段和实体类的映射关系和对数据库执行的SQL语句





    
        
        
        
        
        
        
        
        
    

    
    

9.常量类 FileConstUtil.java 主要定义导出表格中的一些常量,比如标题、表头等等

package com.project.util.file;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @ClassName: FileConstUtil
 * @Description: TODO文件信息常量类
 * @author: HeMengZhu
 * @date: 2018年2月28日 下午4:23:43
 */
public class FileConstUtil {
    /**
     * 导出表格信息
     * @ClassName: DemoStudentMessage
     * @Description: TODO
     * @author: HeMengZhu
     * @date: 2018年2月28日 下午4:24:24
     */
    public static class DemoStudentMessage {
        /**
         * 导出表格名称
         */
        public static final String EXCEL_NAME = "学生信息.xlsx";
        /**
         * 导出表格sheet页名称
         */
        public static final List EXCEL_SHEET_NAME = Arrays.asList("学生信息");
        /**
         * 导出表格sheet页标题
         */
        public static final List EXCEL_TITLE = Arrays.asList("学生信息");
        /**
         * 导出表格sheet页标题行
         */
        public static final List EXCEL_HEADER = getExcelHeader();

        /**
         * 组装各个sheet页标题行为一个list,各个标题行单元格以数组形式组装
         * @Title: getExcelHeader
         * @Description: TODO
         * @return
         * @return: List
         */
        public static List getExcelHeader() {
            List excelHeader = new ArrayList<>();
            String[] title_1 = new String[] { "序号", "姓名", "性别", "电话" };
            excelHeader.add(title_1);
            return excelHeader;
        }
    }
}

10.工具类 ExportExcelUtil.java 主要为导出Excel的数据写入及输出文件流等操作;包括导出单个Sheet页和多个Sheet页的方法。此例为调用多个Sheet页方法

package com.project.util.file;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @ClassName: ExportExcelUtil
 * @Description: TODO
 * @author: HeMengZhu
 * @date: 2018年2月28日 下午5:01:15
 */
@Service
public class ExportExcelUtil {
    private final static String excel2003L = ".xls"; // 2003- 版本的excel
    private final static String excel2007U = ".xlsx"; // 2007+ 版本的excel

    /**
     * 导出Excel:单个sheet页
     * @param fileName 默认导出Excel文件名(带后缀格式)
     * @param title 表标题:可传Null
     * @param titleList 表头
     * @param tableList 数据
     * @param response
     * @throws IOException
     */
    @Transactional
    public void exportExcelUtil(String fileName, String title, List titleList, List tableList, HttpServletResponse response) throws IOException {
        OutputStream os = null;
        XSSFWorkbook wb = new XSSFWorkbook();
        try {
            String name = UUID.randomUUID().toString() + fileName.substring(0, fileName.lastIndexOf("."));
            String ext = fileName.substring(fileName.lastIndexOf("."));
            // 生成临时文件
            File file = File.createTempFile(name, ext);
            XSSFSheet sheet = wb.createSheet(fileName.substring(0, fileName.lastIndexOf(".")));
            XSSFRow row = null;
            XSSFCell cell = null;
            CellStyle css = setTitleStyle(wb); // Excel标题样式
            CellStyle cs = setSimpleCellStyle(wb); // Excel单元格样式
            int row_index = 0;
            // 插入标题
            if (title != null && title.trim().length() != 0) {
                row = sheet.createRow(row_index++);
                cell = row.createCell(0);
                cell.setCellValue(title);
                cell.setCellStyle(css);
            }
            if (titleList != null && title != null && title.trim().length() != 0) {
                sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, titleList.size() - 1));// 横向:合并第一行的第2列到第4列
            }
            // 插入表头
            if (titleList != null) {
                row = sheet.createRow(row_index++);
                for (int i = 0; i < titleList.size(); i++) {
                    cell = row.createCell(i);
                    cell.setCellValue(titleList.get(i));
                    cell.setCellStyle(css);
                    // 自动适应列宽
                    sheet.autoSizeColumn(i);
                }
            }
            // 插入数据
            for (String[] item : tableList) {
                row = sheet.createRow(row_index++); // 创建新的ROW,用于数据插入
                // 将对象数据插入到Excel中
                if (null == item || item.length == 0) {
                    break;
                }
                // Cell赋值开始
                for (int i = 0; i < item.length; i++) {
                    cell = row.createCell(i);
                    cell.setCellValue(item[i]);
                    cell.setCellStyle(cs);
                }
            }
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            os = response.getOutputStream();
            wb.write(os);
            file.delete();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            os.flush();
            os.close();
            wb.close();
        }
    }
    /**
     * 导出Excel:多个sheet页
     * @Title: exportExcelsUtil
     * @Description: TODO
     * @param fileName 默认导出Excel文件名(带后缀格式)
     * @param sheetName 表格多个sheet页名称
     * @param titles 表格多个sheet页标题,可传null
     * @param headerList 表格多个sheet页标题行数据
     * @param tableList 表格多个sheet页表格数据
     * @param response
     * @throws IOException
     * @return: void
     */
    @Transactional
    public void exportExcelsUtil(String fileName, List sheetName, List titles, List headerList, List> tableList, HttpServletResponse response)
            throws IOException {
        OutputStream os = null;
        XSSFWorkbook wb = new XSSFWorkbook();
        try {
            String name = UUID.randomUUID().toString() + fileName.substring(0, fileName.lastIndexOf("."));
            String ext = fileName.substring(fileName.lastIndexOf("."));
            // 生成临时文件
            File file = File.createTempFile(name, ext);
            // 循环创建Sheet页,插入数据
            for (int i = 0; i < sheetName.size(); i++) {
                XSSFSheet sheet = wb.createSheet(sheetName.get(i));
                XSSFRow row = null;
                XSSFCell cell = null;
                CellStyle css = setTitleStyle(wb); // Excel标题样式
                int row_index = 0;
                // 插入标题
                if (titles.get(i) != null && titles.get(i).trim().length() != 0) {
                    row = sheet.createRow(row_index++);
                    cell = row.createCell(0);
                    cell.setCellValue(titles.get(i));
                    cell.setCellStyle(css);
                }
                String[] headerItem = null;
                if (headerList.size() > i && titles.get(i) != null && titles.get(i).trim().length() != 0) {
                    headerItem = headerList.get(i);
                    sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headerItem.length - 1));// 横向:合并第一行的第2列到第4列
                }
                // 插入表头
                if (headerItem != null) {
                    row = sheet.createRow(row_index++);
                    for (int j = 0; j < headerItem.length; j++) {
                        cell = row.createCell(j);
                        cell.setCellValue(headerItem[j]);
                        cell.setCellStyle(css);
                        // 自动适应列宽
                        sheet.autoSizeColumn(j);
                    }
                }
                // 插入数据
                List tableItem = null;
                if (tableList.size() > i) {
                    tableItem = tableList.get(i);
                }
                if (tableItem != null) {
                    for (String[] item : tableItem) {
                        row = sheet.createRow(row_index++); // 创建新的ROW,用于数据插入
                        // 将对象数据插入到Excel中
                        if (null == item || item.length == 0) {
                            break;
                        }
                        // Cell赋值开始
                        for (int k = 0; k < item.length; k++) {
                            CellStyle cs = setSimpleCellStyle(wb); // Excel单元格样式
                            cell = row.createCell(k);
                            cell.setCellValue(item[k]);
                            if (item[k] != null && item[k].length() > 10) {
                                cs.setAlignment(CellStyle.ALIGN_LEFT); // 居左
                            } else {
                                cs.setAlignment(CellStyle.ALIGN_CENTER); // 居中
                            }
                            cell.setCellStyle(cs);
                        }
                    }
                }
            }
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            os = response.getOutputStream();
            wb.write(os);
            file.delete();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            os.flush();
            os.close();
            wb.close();
        }
    }
    /**
     * 描述:根据文件路径获取项目中的文件
     * @param fileDir 文件路径
     * @return
     * @throws Exception
     */
    public File getExcelDemoFile(String fileDir) throws Exception {
        String classDir = null;
        String fileBaseDir = null;
        File file = null;
        classDir = Thread.currentThread().getContextClassLoader().getResource("/").getPath();
        fileBaseDir = classDir.substring(0, classDir.lastIndexOf("classes"));
        file = new File(fileBaseDir + fileDir);
        if (!file.exists()) {
            throw new Exception("模板文件不存在!");
        }
        return file;
    }
    /**
     * 描述:根据文件后缀,自适应模板文件的版本
     * @param inStr,fileName
     * @return
     * @throws Exception
     */
    public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
        Workbook wb = null;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (excel2003L.equals(fileType)) {
            wb = new HSSFWorkbook(inStr);
        } else if (excel2007U.equals(fileType)) {
            wb = new XSSFWorkbook(inStr);
        } else {
            throw new Exception("解析的文件格式有误!");
        }
        return wb;
    }
    /**
     * 描述:设置简单的Cell样式
     * @return
     */
    public CellStyle setSimpleCellStyle(Workbook wb) {
        CellStyle cs = wb.createCellStyle();
        cs.setBorderBottom(CellStyle.BORDER_THIN); // 下边框
        cs.setBorderLeft(CellStyle.BORDER_THIN);// 左边框
        cs.setBorderTop(CellStyle.BORDER_THIN);// 上边框
        cs.setBorderRight(CellStyle.BORDER_THIN);// 右边框
        cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);// 垂直居中
        cs.setWrapText(true);// 自动换行
        return cs;
    }
    /**
     * 描述:设置表头样式
     * @param workbook
     * @return
     */
    public CellStyle setTitleStyle(Workbook workbook) {
        CellStyle cs = workbook.createCellStyle();
        cs.setBorderBottom(CellStyle.BORDER_THIN); // 下边框
        cs.setBorderLeft(CellStyle.BORDER_THIN);// 左边框
        cs.setBorderTop(CellStyle.BORDER_THIN);// 上边框
        cs.setBorderRight(CellStyle.BORDER_THIN);// 右边框
        cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);// 垂直居中
        cs.setAlignment(CellStyle.ALIGN_CENTER); // 居中
        // 设置字体:
        Font font = workbook.createFont();
        font.setFontName("黑体");
        font.setFontHeightInPoints((short) 12);// 设置字体大小
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 粗体显示
        cs.setFont(font);
        return cs;
    }
}

你可能感兴趣的:(POI实现导出Excel)