VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Java教程 >
  • poi导出Excel复杂表头的处理

一直在写poi导出表头的时候,发现没有现成的复杂格式的表头的工具类,这类给大家提供一个,我们传入三个参数 head ,title,data,就能为我们创建表头和excel

 

 

效果图 

 

<dependencies>
    <dependency>
        <groupId>;.org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.1.2</version>
    </dependency>

    <dependency>
        <groupId>;.org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.1.2</version>
    </dependency>

</dependencies>
添加依赖

public class TestData {

    public static List<String> getHead() {
        List<String> strings = Arrays.asList("一级标题", "二级标题");
        return strings;
    }

    public static List<Map<String, Object>> getTitles() {

        List<Map<String, Object>> titles = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Map<String, Object> t = new HashMap<>();
            t.put("key", "key" + i);
            t.put("name", "名称" + i);
            titles.add(t);
        }

        // 创建二级标题
        List<Map<String, Object>> titles2 = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Map<String, Object> t = new HashMap<>();
            t.put("key", "key2." + i);
            t.put("name", "名称2." + i);
            titles2.add(t);
        }
        titles.get(2).put("children", titles2);


        // 创建三级标题
        List<Map<String, Object>> titles3 = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Map<String, Object> t = new HashMap<>();
            t.put("key", "key5." + i);
            t.put("name", "名称5." + i);
            titles3.add(t);
        }
        List<Map<String, Object>> titles4 = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Map<String, Object> t = new HashMap<>();
            t.put("key", "key5.2." + i);
            t.put("name", "名称5.2." + i);
            titles4.add(t);
        }
        List<Map<String, Object>> titles5 = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            Map<String, Object> t = new HashMap<>();
            t.put("key", "key5.2.1." +i);
            t.put("name", "名称5.2.1." + i);
            titles5.add(t);
        }
        titles4.get(1).put("children", titles5);
        titles3.get(2).put("children", titles4);
        titles.get(5).put("children", titles3);
        return titles;
    }

    public static List<Map<String, Object>> getTestData(List<String> index) {
        List<Map<String, Object>> data = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            HashMap<String, Object> map = new HashMap<>();
            for (int j = 0; j < index.size(); j++) {
                map.put(index.get(j), "数据data" + j);
            }
            data.add(map);
        }
        return data;
    }
}
---- 以上是传入的参数格式
下面是具体实现代码
public class Main {
    public static void main(String[] args) {
        File file = new File("F:\\test\\data\\test.xls");
        try {
            FileOutputStream outfile = new FileOutputStream(file);
            List<String> head = TestData.getHead();
            List<Map<String, Object>> titles = TestData.getTitles();
            Workbook workBook = getWorkBook(head, titles, null);
            workBook.write(outfile);
            outfile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static Workbook getWorkBook(List<String> head, List<Map<String, Object>> titles, List<Map<String, Object>> data) throws Exception {


        //全部的列,并判断数据格式是否正确
        List<Map<String, Object>> alltitles = new ArrayList<>();
        getProperty(titles, alltitles);
        // 存储数据的key对应的excel索引
        List<String> columIndex = new ArrayList<>();
        getDataIndex(titles, columIndex);
        int allwidth = columIndex.size();

        Workbook work = new HSSFWorkbook();
        CellStyle headStyle = getHeadStyle(work);
        CellStyle titleStyle = getTitleStyle(work);
        CellStyle dataStyle = getDataStyle(work);

        Sheet sheet = work.createSheet();
        //设置单元格宽度
        sheet.setDefaultColumnWidth(18);

        int headHeight = head == null ? 0 : head.size();
        int titleHeight = getMaxDeep(titles);

        //创建头标题
        for (int i = 0; i < headHeight; i++) {
            Row row = sheet.createRow(i);
            row.setHeightInPoints(30);
            Cell cell = row.createCell(0);
            CellRangeAddress region = new CellRangeAddress(i, i, 0, allwidth-1);
            sheet.addMergedRegion(region);
            cell.setCellValue(head.get(i));
        }
        setStyle(work,sheet,0,2,0,allwidth,headStyle);
        //创建表头
        for (int i = 0; i < titleHeight; i++) {
            int height = i + headHeight ;
            Row row = sheet.createRow(height);
            for (int j = 0; j < alltitles.size(); j++) {
                Map<String, Object> colum = alltitles.get(j);
                Integer level = Integer.valueOf(colum.get("level").toString());
                if (level == i) {
                    int left = Integer.valueOf(colum.get("left").toString());
                    int width = Integer.valueOf(colum.get("width").toString());
                    Cell cell = row.createCell(left);
                    //判断横向合
                    int toMergeCol = left+width-1;
                    //判断是否需要纵向合并
                    int toMergeRow = hasChildren(colum) ? height : headHeight+titleHeight-1;

                    if(left!=toMergeCol || height != toMergeRow){
                        CellRangeAddress region = new CellRangeAddress(height, toMergeRow, left, toMergeCol);
                        sheet.addMergedRegion(region);
                    }
                    cell.setCellValue(colum.get("name").toString());
                }
            }
        }
         //  表头设置样式
        setStyle(work,sheet,headHeight,headHeight+titleHeight,0,allwidth,titleStyle);

        // 创建数据,后续工具类的data是传过来的
        List<Map<String, Object>> testData = TestData.getTestData(columIndex);

        for(int i = 0 ; i < testData.size();i++ ){
            Row row = sheet.createRow(headHeight + titleHeight + i);
            Map<String, Object> res = testData.get(i);
            row.setHeightInPoints((short)20);
            for(int j = 0 ;j < columIndex.size();j++){
                Cell cell = row.createCell(j);
                cell.setCellStyle(dataStyle);
                cell.setCellValue(res.get(columIndex.get(j)).toString());
            }
        }

        return work;

    }

    private static void getProperty(List<Map<String, Object>> treetitles,List<Map<String, Object>> listtitles) {
        Map<String,Integer> left = new HashMap<>();
        left.put("left",0);
        addAllColum(treetitles,listtitles,0,left);
    }



    /**
     * 查询这个节点的树的最大宽度
     *
     * @param o
     * @return
     */
    private static int getMaxWidth(Object o) {
        int res = 0;
        if (o == null) {
            return res;
        }
        if (o instanceof Map) {
            Map map = (Map) o;
            return hasChildren(map) ? getMaxWidth(map.get("children")) : 1;
        } else if (o instanceof List) {
            List list = (List) o;
            for (int i = 0; i < list.size(); i++) {
                Map map = (Map) list.get(i);
                int width = hasChildren(map) ?  getMaxWidth(map.get("children")) : 1;
                res = res + width;
            }
        }
        return res;
    }

    /**
     * 获取excel的data的数据位于key的index
     *
     * @param titles
     * @param colum
     */
    private static void getDataIndex(List<Map<String, Object>> titles, List<String> colum) {

        if (titles == null || titles.size() == 0) {
            return;
        }

        for (int i = 0; i < titles.size(); i++) {
            Map<String, Object> map = titles.get(i);
            if (hasChildren(map)) {
                List<Map<String, Object>> children = (List<Map<String, Object>>) map.get("children");
                getDataIndex(children, colum);
            } else {
                colum.add(map.get("key").toString());
            }

        }
    }

    /**
     * 将树的所有节点放在一个list中
     *
     * @param titles  树结构的title
     * @param all     存放全部节点的list
     * @param deep  当前节点的深度
     * @param left  当前节点左边Excel的索引距离,(即当前节点左边没有子节点的节点个数)
     */
    private static void addAllColum(List<Map<String, Object>> titles, List<Map<String, Object>> all, Integer deep, Map<String,Integer> left) {
        if (titles == null || titles.size() == 0) {
            return;
        }

        for (int i = 0; i < titles.size(); i++) {
            Map<String, Object> t = titles.get(i);
              if(t.get("key")==null){
                throw new RuntimeException("节点的key不能为null");
              }
            t.put("left", left.get("left"));
            t.put("level", deep);
            t.put("width",getMaxWidth(t));
            if(!hasChildren(t)){
                left.put("left",left.get("left")+1);
            }

            if (hasChildren(t)) {
                addAllColum((List<Map<String, Object>>) t.get("children"), all, deep + 1, left);
            }
          // 查看是否有重复的key,重复的key就抛出参数不合法异常
           for(int k =0 ; k < all.size(); k++){
               Map<String, Object> before = all.get(k);
               if(before.get("key").toString().equals(t.get("key"))){
                   throw new RuntimeException("节点的key:"+t.get("key")+"不能重复");
               }
           }
            all.add(t);
        }
    }

    /**
     * 获取这个节点的最大深度
     *
     * @param o
     * @return
     */
    public static int getMaxDeep(Object o) {
        if (o == null) {
            return 0;
        }
        HashMap<String, Integer> deep = new HashMap<>();
        deep.put("deep", 1);
        if (o instanceof List) {
            List<Map<String, Object>> list = (List<Map<String, Object>>) o;
            toNextDeep(list, 1, deep);
        } else if (o instanceof Map) {
            Map map = (Map) o;
            if (hasChildren(map)) {
                List<Map<String, Object>> children = (List<Map<String, Object>>) map.get("children");
                toNextDeep(children, 2, deep);
            }
        }

        return deep.get("deep");
    }


    private static void toNextDeep(List<Map<String, Object>> titles, int level, HashMap<String, Integer> deep) {
        if (titles != null && titles.size() == 0) {
            return;
        }
        if (deep.get("deep") < level) {
            deep.put("deep", level);
        }
        for (int i = 0; i < titles.size(); i++) {
            Map<String, Object> map = titles.get(i);
            if (hasChildren(map)) {
                toNextDeep((List<Map<String, Object>>) map.get("children"), level + 1, deep);
            }
        }
    }

    private static boolean hasChildren(Object o){
        if(o == null){
            return false;
        }
        Map map=(Map)o;
        if(map.get("children")!=null && map.get("children") instanceof List){
            List list = (List)map.get("children");
            return list.size()!=0;
        }

        return false;
    }

    private static CellStyle getHeadStyle(Workbook wb) throws Exception {
        CellStyle head = wb.createCellStyle();
        head.setBorderTop(BorderStyle.THIN);
        head.setBorderRight(BorderStyle.THIN);
        head.setBorderBottom(BorderStyle.THIN);
        head.setBorderLeft(BorderStyle.THIN);

        head.setVerticalAlignment(VerticalAlignment.CENTER);
        head.setAlignment(HorizontalAlignment.CENTER);

        head.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.index);
        head.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        Font font = wb.createFont();

        font.setFontName("仿宋_GB2312");
        font.setColor(IndexedColors.WHITE.index);
        font.setFontHeight((short) 24);
        font.setFontHeightInPoints((short) 26);
        head.setFont(font);
        return head;
    }
    private static CellStyle getTitleStyle(Workbook wb) throws Exception {
        CellStyle head = wb.createCellStyle();
        head.setBorderTop(BorderStyle.THIN);
        head.setBorderRight(BorderStyle.THIN);
        head.setBorderBottom(BorderStyle.THIN);
        head.setBorderLeft(BorderStyle.THIN);

        head.setVerticalAlignment(VerticalAlignment.CENTER);
        head.setAlignment(HorizontalAlignment.CENTER);

        head.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
        head.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        Font font = wb.createFont();

        font.setFontName("仿宋_GB2312");
        font.setFontHeight((short) 18);
        font.setFontHeightInPoints((short) 18);
        head.setFont(font);
        return head;
    }

    private static CellStyle getDataStyle(Workbook wb) throws Exception {
        CellStyle head = wb.createCellStyle();
        head.setBorderTop(BorderStyle.THIN);
        head.setBorderRight(BorderStyle.THIN);
        head.setBorderBottom(BorderStyle.THIN);
        head.setBorderLeft(BorderStyle.THIN);

        head.setVerticalAlignment(VerticalAlignment.CENTER);
        head.setAlignment(HorizontalAlignment.CENTER);

        Font font = wb.createFont();

        font.setFontName("仿宋_GB2312");
        font.setFontHeight((short) 14);
        font.setFontHeightInPoints((short) 14);
        head.setFont(font);
        return head;
    }

    private static void setStyle(Workbook work,Sheet sheet,int rowfrom ,int rowto,int colfrom,int cellto,CellStyle style){

        //添加全局样式
        for(int i = rowfrom; i < rowto ;i++){
            Row cells = sheet.getRow(i) == null ? sheet.createRow(i) : sheet.getRow(i);
            for(int j = colfrom ; j <cellto ;j++){
                Cell cell = cells.getCell(j) == null ? cells.createCell(j) : cells.getCell(j);
                cell.setCellStyle(style);
            }
        }
    }
}


出处:https://www.cnblogs.com/poi-Excel/p/15137585.html


      



  

相关教程