zoukankan      html  css  js  c++  java
  • Excel导出工具

    接到需求是需要导出一个多sheet的excel,于是寻找jeesite中的excel导入工具,但发现工具只能支持一个sheet的导出,于是自己将工具修改了一下,支持了多sheet

    导出。

    /**
     * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
     */
    package com.xzny.opt.common.utils.excel;
    
    import com.google.common.collect.Lists;
    import com.xzny.opt.common.utils.Encodes;
    import com.xzny.opt.common.utils.Reflections;
    import com.xzny.opt.common.utils.excel.annotation.ExcelField;
    import com.xzny.opt.modules.sys.utils.DictUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
    import org.apache.poi.xssf.usermodel.XSSFRichTextString;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.*;
    
    /**
     * 导出Excel文件工具类(导出“XLSX”格式,支持大数据量导出   @see org.apache.poi.ss.SpreadsheetVersion)
     * 能够支持一个文件多个sheet
     * @author kongweiteng
     * @version 2017-10-17
     */
    public class ExportExcelUtil {
    
        private static Logger log = LoggerFactory.getLogger(ExportExcelUtil.class);
    
        /**
         * 工作薄对象
         */
        private SXSSFWorkbook wb;
    
        /**
         * 工作表对象
         */
        /*private Sheet sheet;*/
    
        /**
         * 样式列表
         */
        private Map<String, CellStyle> styles;
    
        /**
         * 当前行号
         */
        private int rownum;
        Map<String,Integer> rownumMap= new LinkedHashMap<String, Integer>();
    
        /**
         * 注解列表(Object[]{ ExcelField, Field/Method })
         */
        /*List<Object[]> annotationList = Lists.newArrayList();*/
        Map<String,List<Object[]>> annotationMap = new LinkedHashMap<String,List<Object[]>>();
    
        /**
         * 构造函数
         *
         * @param title 表格标题,传“空值”,表示无标题
         * @param cls   实体对象,通过annotation.ExportField获取标题
         */
        /*public ExportExcelUtil(String title, Class<?> cls) {
            this(title, cls, 1);
        }*/
    
        /**
         * 构造函数
         * @param clsMap
         * @param type
         * @param groups
         */
        public ExportExcelUtil(Map<String,Class<?>> clsMap, int type, int... groups) {
            Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
            
            //遍历多个sheet信息的map
            for(Map.Entry<String,Class<?>> entry:clsMap.entrySet()){
                List<Object[]> annotationList = Lists.newArrayList();
                String title = entry.getKey();
                Class<?> cls = entry.getValue();
                // Get annotation field
                Field[] fs = cls.getDeclaredFields();
                for (Field f : fs) {
                    ExcelField ef = f.getAnnotation(ExcelField.class);
                    if (ef != null && (ef.type() == 0 || ef.type() == type)) {
                        if (groups != null && groups.length > 0) {
                            boolean inGroup = false;
                            for (int g : groups) {
                                if (inGroup) {
                                    break;
                                }
                                for (int efg : ef.groups()) {
                                    if (g == efg) {
                                        inGroup = true;
                                        annotationList.add(new Object[]{ef, f});
                                        break;
                                    }
                                }
                            }
                        } else {
                            annotationList.add(new Object[]{ef, f});
                        }
                    }
                }
                // Get annotation method
                Method[] ms = cls.getDeclaredMethods();
                for (Method m : ms) {
                    ExcelField ef = m.getAnnotation(ExcelField.class);
                    if (ef != null && (ef.type() == 0 || ef.type() == type)) {
                        if (groups != null && groups.length > 0) {
                            boolean inGroup = false;
                            for (int g : groups) {
                                if (inGroup) {
                                    break;
                                }
                                for (int efg : ef.groups()) {
                                    if (g == efg) {
                                        inGroup = true;
                                        annotationList.add(new Object[]{ef, m});
                                        break;
                                    }
                                }
                            }
                        } else {
                            annotationList.add(new Object[]{ef, m});
                        }
                    }
                }
                // Field sorting
                Collections.sort(annotationList, new Comparator<Object[]>() {
                    public int compare(Object[] o1, Object[] o2) {
                        return new Integer(((ExcelField) o1[0]).sort()).compareTo(
                                new Integer(((ExcelField) o2[0]).sort()));
                    }
    
                    ;
                });
                // Initialize
                List<String> headerList = Lists.newArrayList();
                for (Object[] os : annotationList) {
                    String t = ((ExcelField) os[0]).title();
                    // 如果是导出,则去掉注释
                    if (type == 1) {
                        String[] ss = StringUtils.split(t, "**", 2);
                        if (ss.length == 2) {
                            t = ss[0];
                        }
                    }
                    headerList.add(t);
                }
                headerMap.put(title,headerList);
                annotationMap.put(title,annotationList);
            }
    
            initialize(headerMap,annotationMap);
        }
    
       /* *//**
         * 构造函数
         *
         * @param title   表格标题,传“空值”,表示无标题
         * @param headers 表头数组
         *//*
        public ExportExcelUtil(String title, String[] headers) {
            initialize(Lists.newArrayList(headers));
        }*/
    
        /**
         * 构造函数
         *
         * @param title      表格标题,传“空值”,表示无标题
         * @param headerList 表头列表
         */
        /*public ExportExcelUtil(String title, List<String> headerList) {
            initialize(title, headerList);
        }*/
    
        /**
         * 初始化函数
         * @param headerMap
         */
        private void initialize( Map<String, List<String>> headerMap,Map<String,List<Object[]>> annotationMap) {
            this.wb = new SXSSFWorkbook(500);
    
            //遍历map创建响应的sheet
            for (Map.Entry<String, List<String>> entry : headerMap.entrySet()) {
                int rownum=0;
                String key = entry.getKey();
                List<String> headerList = entry.getValue();
                Sheet sheet = wb.createSheet(key);
                this.styles = createStyles(wb);
                // Create title
                if (StringUtils.isNotBlank(key)) {
                    Row titleRow = sheet.createRow(rownum++);
                    titleRow.setHeightInPoints(30);
                    Cell titleCell = titleRow.createCell(0);
                    titleCell.setCellStyle(styles.get("title"));
                    titleCell.setCellValue(key);
                    sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(),
                            titleRow.getRowNum(), titleRow.getRowNum(), headerList.size() - 1));
                }
                // Create header
                if (headerList == null) {
                    throw new RuntimeException("headerList not null!");
                }
                Row headerRow = sheet.createRow(rownum++);
                headerRow.setHeightInPoints(16);
                for (int i = 0; i < headerList.size(); i++) {
                    Cell cell = headerRow.createCell(i);
                    cell.setCellStyle(styles.get("header"));
                    String[] ss = StringUtils.split(headerList.get(i), "**", 2);
                    if (ss.length == 2) {
                        cell.setCellValue(ss[0]);
                        Comment comment = sheet.createDrawingPatriarch().createCellComment(
                                new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));
                        comment.setString(new XSSFRichTextString(ss[1]));
                        cell.setCellComment(comment);
                    } else {
                        cell.setCellValue(headerList.get(i));
                    }
                    sheet.autoSizeColumn(i);
                }
                for (int i = 0; i < headerList.size(); i++) {
                    int colWidth = sheet.getColumnWidth(i) * 2;
                    sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);
                }
                log.debug("Initialize success.");
                rownumMap.put(key,rownum);
            }
    
    
        }
    
        /**
         * 创建表格样式
         *
         * @param wb 工作薄对象
         * @return 样式列表
         */
        private Map<String, CellStyle> createStyles(Workbook wb) {
            Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
    
            CellStyle style = wb.createCellStyle();
            style.setAlignment(CellStyle.ALIGN_CENTER);
            style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
            Font titleFont = wb.createFont();
            titleFont.setFontName("Arial");
            titleFont.setFontHeightInPoints((short) 16);
            titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
            style.setFont(titleFont);
            styles.put("title", style);
    
            style = wb.createCellStyle();
            style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
            style.setBorderRight(CellStyle.BORDER_THIN);
            style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderLeft(CellStyle.BORDER_THIN);
            style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderTop(CellStyle.BORDER_THIN);
            style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderBottom(CellStyle.BORDER_THIN);
            style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            Font dataFont = wb.createFont();
            dataFont.setFontName("Arial");
            dataFont.setFontHeightInPoints((short) 10);
            style.setFont(dataFont);
            styles.put("data", style);
    
            style = wb.createCellStyle();
            style.cloneStyleFrom(styles.get("data"));
            style.setAlignment(CellStyle.ALIGN_LEFT);
            styles.put("data1", style);
    
            style = wb.createCellStyle();
            style.cloneStyleFrom(styles.get("data"));
            style.setAlignment(CellStyle.ALIGN_CENTER);
            styles.put("data2", style);
    
            style = wb.createCellStyle();
            style.cloneStyleFrom(styles.get("data"));
            style.setAlignment(CellStyle.ALIGN_RIGHT);
            styles.put("data3", style);
    
            style = wb.createCellStyle();
            style.cloneStyleFrom(styles.get("data"));
    //        style.setWrapText(true);
            style.setAlignment(CellStyle.ALIGN_CENTER);
            style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setFillPattern(CellStyle.SOLID_FOREGROUND);
            Font headerFont = wb.createFont();
            headerFont.setFontName("Arial");
            headerFont.setFontHeightInPoints((short) 10);
            headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
            headerFont.setColor(IndexedColors.WHITE.getIndex());
            style.setFont(headerFont);
            styles.put("header", style);
    
            return styles;
        }
    
        /**
         * 添加一行
         *
         * @return 行对象
         */
        /*public Row addRow() {
            return sheet.createRow(rownum++);
        }*/
    
    
        /**
         * 添加一个单元格
         *
         * @param row    添加的行
         * @param column 添加列号
         * @param val    添加值
         * @return 单元格对象
         */
        public Cell addCell(Row row, int column, Object val) {
            return this.addCell(row, column, val, 0, Class.class);
        }
    
        /**
         * 添加一个单元格
         *
         * @param row    添加的行
         * @param column 添加列号
         * @param val    添加值
         * @param align  对齐方式(1:靠左;2:居中;3:靠右)
         * @return 单元格对象
         */
        public Cell addCell(Row row, int column, Object val, int align, Class<?> fieldType) {
            Cell cell = row.createCell(column);
            String cellFormatString = "@";
            try {
                if (val == null) {
                    cell.setCellValue("");
                } else if (fieldType != Class.class) {
                    cell.setCellValue((String) fieldType.getMethod("setValue", Object.class).invoke(null, val));
                } else {
                    if (val instanceof String) {
                        cell.setCellValue((String) val);
                    } else if (val instanceof Integer) {
                        cell.setCellValue((Integer) val);
                        cellFormatString = "0";
                    } else if (val instanceof Long) {
                        cell.setCellValue((Long) val);
                        cellFormatString = "0";
                    } else if (val instanceof Double) {
                        cell.setCellValue((Double) val);
                        cellFormatString = "0.00";
                    } else if (val instanceof Float) {
                        cell.setCellValue((Float) val);
                        cellFormatString = "0.00";
                    } else if (val instanceof Date) {
                        cell.setCellValue((Date) val);
                        cellFormatString = "yyyy-MM-dd HH:mm";
                    } else {
                        cell.setCellValue((String) Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(),
                                "fieldtype." + val.getClass().getSimpleName() + "Type")).getMethod("setValue", Object.class).invoke(null, val));
                    }
                }
                if (val != null) {
                    CellStyle style = styles.get("data_column_" + column);
                    if (style == null) {
                        style = wb.createCellStyle();
                        style.cloneStyleFrom(styles.get("data" + (align >= 1 && align <= 3 ? align : "")));
                        style.setDataFormat(wb.createDataFormat().getFormat(cellFormatString));
                        styles.put("data_column_" + column, style);
                    }
                    cell.setCellStyle(style);
                }
            } catch (Exception ex) {
                log.info("Set cell value [" + row.getRowNum() + "," + column + "] error: " + ex.toString());
                cell.setCellValue(val.toString());
            }
            return cell;
        }
    
        /**
         * 添加数据(通过annotation.ExportField添加数据)
         *
         * @return list 数据列表
         */
        public <E> ExportExcelUtil setDataList(Map<String,List<E>> dataMap) {
            int rownum;
            for (Map.Entry<String,List<E>> entry:dataMap.entrySet()){
                String sheetName = entry.getKey();//sheet名称
                rownum=rownumMap.get(sheetName);//获取本sheet的row行数
                //根据sheet名称获取sheet对象
                Sheet fileSheet = getSheet(sheetName);
                List<E> list = entry.getValue();
                for (E e : list) {
                    int colunm = 0;
                    Row row = fileSheet.createRow(rownum++);
                    StringBuilder sb = new StringBuilder();
                    List<Object[]> annotationList = annotationMap.get(sheetName);
                    for (Object[] os : annotationList) {
                        ExcelField ef = (ExcelField) os[0];
                        Object val = null;
                        // Get entity value
                        try {
                            if (StringUtils.isNotBlank(ef.value())) {
                                val = Reflections.invokeGetter(e, ef.value());
                            } else {
                                if (os[1] instanceof Field) {
                                    val = Reflections.invokeGetter(e, ((Field) os[1]).getName());
                                } else if (os[1] instanceof Method) {
                                    val = Reflections.invokeMethod(e, ((Method) os[1]).getName(), new Class[]{}, new Object[]{});
                                }
                            }
                            // If is dict, get dict label
                            if (StringUtils.isNotBlank(ef.dictType())) {
                                val = DictUtils.getDictLabel(val == null ? "" : val.toString(), ef.dictType(), "");
                            }
                        } catch (Exception ex) {
                            // Failure to ignore
                            log.info(ex.toString());
                            val = "";
                        }
                        this.addCell(row, colunm++, val, ef.align(), ef.fieldType());
                        sb.append(val + ", ");
                    }
                    log.debug("Write success: [" + row.getRowNum() + "] " + sb.toString());
                }
            }
            return this;
        }
    
        /**
         * 根据sheet名称获取sheet
         * @param sheetName
         * @return
         */
        public Sheet getSheet(String sheetName){
            Sheet sheet = wb.getSheet(sheetName);
            return sheet;
        }
    
        /**
         * 输出数据流
         *
         * @param os 输出数据流
         */
        public ExportExcelUtil write(OutputStream os) throws IOException {
            wb.write(os);
            return this;
        }
    
        /**
         * 输出到客户端
         *
         * @param fileName 输出文件名
         */
        public ExportExcelUtil write(HttpServletResponse response, String fileName) throws IOException {
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode(fileName));
            write(response.getOutputStream());
            return this;
        }
    
        /**
         * 输出到文件
         *
         * @param
         */
        public ExportExcelUtil writeFile(String name) throws FileNotFoundException, IOException {
            FileOutputStream os = new FileOutputStream(name);
            this.write(os);
            return this;
        }
    
        /**
         * 清理临时文件
         */
        public ExportExcelUtil dispose() {
            wb.dispose();
            return this;
        }
    
    //    /**
    //     * 导出测试
    //     */
    //    public static void main(String[] args) throws Throwable {
    //        
    //        List<String> headerList = Lists.newArrayList();
    //        for (int i = 1; i <= 10; i++) {
    //            headerList.add("表头"+i);
    //        }
    //        
    //        List<String> dataRowList = Lists.newArrayList();
    //        for (int i = 1; i <= headerList.size(); i++) {
    //            dataRowList.add("数据"+i);
    //        }
    //        
    //        List<List<String>> dataList = Lists.newArrayList();
    //        for (int i = 1; i <=1000000; i++) {
    //            dataList.add(dataRowList);
    //        }
    //
    //        ExportExcel ee = new ExportExcel("表格标题", headerList);
    //        
    //        for (int i = 0; i < dataList.size(); i++) {
    //            Row row = ee.addRow();
    //            for (int j = 0; j < dataList.get(i).size(); j++) {
    //                ee.addCell(row, j, dataList.get(i).get(j));
    //            }
    //        }
    //        
    //        ee.writeFile("target/export.xlsx");
    //
    //        ee.dispose();
    //        
    //        log.debug("Export success.");
    //        
    //    }
    
    }

    使用工具类进行导出文件的方法示例:

    @RequestMapping(value = "export")
        public String exportFile(Model model,String custNo,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
            try {
                Map<String,Class<?>> clsMap = new LinkedHashMap<String, Class<?>>();
                Map<String,List<ExportModel>> dataMap = new LinkedHashMap<String, List<ExportModel>>();
                String fileName = "客户电量数据"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
                //查询图一数据
                List<ExportModel> cusAccount = cusQuantityExportService.getCusAccount(custNo);
                dataMap.put("客户电量数据("+custNo+")",cusAccount);
                clsMap.put("客户电量数据("+custNo+")",ExportModel.class);
                //查询图三数据
                List<ExportModel> cusRatio = cusQuantityExportService.getCusRatio(custNo);
                dataMap.put("客户电量同比数据("+custNo+")",cusRatio);
                clsMap.put("客户电量同比数据("+custNo+")",ExportModel.class);
                new ExportExcelUtil(clsMap,1).setDataList(dataMap).write(response, fileName).dispose();
                return null;
            } catch (Exception e) {
                addMessage(redirectAttributes, "导出用户失败!失败信息:"+e.getMessage());
            }
            model.addAttribute("custNo",custNo);
            return "redirect:" + adminPath + "/anal/monthlyElectricity";
        }
  • 相关阅读:
    C. Shaass and Lights 解析(思維、組合)
    D. Binary String To Subsequences(队列)(贪心)
    CodeForces 1384B2. Koa and the Beach (Hard Version)(贪心)
    CodeForces 1384B1. Koa and the Beach (Easy Version)(搜索)
    CodeForces 1384C. String Transformation 1(贪心)(并查集)
    CodeForces 1384A. Common Prefixes
    POJ-2516 Minimum Cost(最小费用最大流)
    POJ3261-Milk Patterns(后缀数组)
    HDU-1300 Pearls(斜率DP)
    HDU-4528 小明系列故事-捉迷藏(BFS)
  • 原文地址:https://www.cnblogs.com/kongweiteng/p/7681129.html
Copyright © 2011-2022 走看看