做 oa 系统的都会有这个要求: 根据数据导入 excel 文件. 只需要点击一下, 你所需要的数据就直接生成一个 excel 文件了, 是不是很方便?
是的没错, 很方便, 但是对于我们来说是一件很痛苦的事情, 所以说一下我的经历. 因为是第一次写 excel 文件导出, 所以代码可能写的很烂, 不喜勿喷.
有什么意见也可以直接留言哦, 希望与大家一起交流
第一步, 先在 pom.xml 文件依赖 jar 包:
- <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi</artifactId>
- <version>3.6</version>
- </dependency>
第二部, 我们开始写工具类了:
第一个工具类创建 excel 表单内容:
- public class CreateExcelUtil{
- /**
- * 导出 Excel
- * @param sheetName sheet 名称
- * @param title 标题
- * @param values 内容
- * @param wb HSSFWorkbook 对象
- * @return
- */
- public static HSSFWorkbook getHSSFWorkbook(String sheetName, String []title, String [][]values, HSSFWorkbook wb){
- // 第一步, 创建一个 HSSFWorkbook, 对应一个 Excel 文件
- if(wb == null){
- wb = new HSSFWorkbook();
- }
- // 第二步, 在 workbook 中添加一个 sheet, 对应 Excel 文件中的 sheet
- HSSFSheet sheet = wb.createSheet(sheetName);
- // 默认宽度
- sheet.setDefaultColumnWidth(25);
- // 默认高度
- sheet.setDefaultRowHeightInPoints(20);
- // 第三步, 在 sheet 中添加表头第 0 行, 注意老版本 poi 对 Excel 的行数列数有限制
- HSSFRow row = sheet.createRow(0);
- sheet.autoSizeColumn(1,true);// 宽度自适应
- // 第四步, 创建单元格, 并设置值表头 设置表头居中
- HSSFCellStyle style = wb.createCellStyle();
- style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
- // 声明列对象
- HSSFCell cell = null;
- // 创建标题
- for(int i=0;i<title.length;i++){
- cell = row.createCell(i);
- cell.setCellValue(title[i]);
- cell.setCellStyle(style);
- }
- // 创建内容
- for(int i=0;i<values.length;i++){
- row = sheet.createRow(i + 1);
- for(int j=0;j<values[i].length;j++){
- // 将内容按顺序赋给对应的列对象
- row.createCell(j).setCellValue(values[i][j]);
- }
- }
- return wb;
- }
- }
第二个工具类: 通过流的方式响应回客户端
- public class ExcelPortUtil{
- // 发送响应流方法
- public static void setResponseHeader(HttpServletResponse response, String fileName,String[]title,String[][]content) {
- try {
- // 创建 HSSFWorkbook
- HSSFWorkbook wb = CreateExcelUtil.getHSSFWorkbook(fileName, title, content, null);
- try {
- fileName = new String(fileName.getBytes(),"ISO8859-1");
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- response.setContentType("application/octet-stream;charset=ISO8859-1");
- response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
- response.addHeader("Param", "no-cache");
- response.addHeader("Cache-Control", "no-cache");
- OutputStream os = response.getOutputStream();
- wb.write(os);
- os.flush();
- os.close();
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- // 根据参数返回一个二维数组
- public static String[][] getContent(int length){
- return new String[length][];
- }
- // 获取 properties 文件并解决中文乱码问题
- public static Properties getProperties() throws IOException {
- Properties prop = new Properties();
- prop.load(new InputStreamReader(Client.class.getClassLoader().getResourceAsStream("reportForm.properties"), "UTF-8"));
- return prop;
- }
- // public static void main(String[] args) throws IOException {
- // Properties pro = ExcelPortUtil.getProperties();
- // System.out.println(pro.getProperty("whMaterialClass.typeName"));
- // }
- }
因为 excel 表单行头是可以变化的, 所以我们应该写一个 property 文件, 这样我们维护起来也方便
#excel 文件信息
ex.excelFileName = 数据信息表
# 物质类型管理信息
whMaterialClass.fileName = 物质分类信息表
whMaterialClass.typeName = 物质类型名称
whMaterialClass.state = 物质类型代码
whMaterialClass.remark = 物质类型备注
然后我们需要在业务层麻烦一点:
- /**
- * 生成 excel 文件
- * @param param
- * @param response
- * @throws IOException
- */
- public void excelPort(WhMaterialClassParam param, HttpServletResponse response) throws IOException {
- Properties pro = ExcelPortUtil.getProperties();
- // 获取数据
- List<WhMaterialClass> list = whMaterialClassMapper.getAllBySeach(param);
- //excel 标题
- String[] title = {
- pro.getProperty("whMaterialClass.typeName"),
- pro.getProperty("whMaterialClass.state"),
- pro.getProperty("whMaterialClass.remark")
- };
- // 数据
- String[][] content = ExcelPortUtil.getContent(list.size());
- for (int i = 0; i < list.size(); i++) {
- WhMaterialClass wms = list.get(i);
- content[i] = new String[title.length];
- content[i][0] = wms.getMaterialClassName();
- content[i][1] = wms.getMaterialClassCode();
- content[i][2] = wms.getRemark();
- }
- ExcelPortUtil.setResponseHeader(response,pro.getProperty("whMaterialClass.fileName"),title,content);
- }
来源: http://www.bubuko.com/infodetail-2600241.html