我是靠谱客的博主 甜美芝麻,最近开发中收集的这篇文章主要介绍poi实现单元格行合并,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

首先展示出来的效果图,避免浪费大家查找的时间
在这里插入图片描述

效果如上;前后列合并,中间列不合并

代码如下:

方法参数:  List<OrderExcl> orders,  一行记录对应一个类 

   		XSSFWorkbook wb = new XSSFWorkbook();
   		//sheet的名字
        XSSFSheet sheet = wb.createSheet("订单列表");
        //设置默认列宽和行高
        sheet.setDefaultColumnWidth((short) 20);
        sheet.setDefaultRowHeightInPoints(20);
        //标题行,第0行数据,就是图片上的蓝色行
        XSSFRow row = sheet.createRow(0);
        String[] str = {"业务员",  "客户姓名", "客户电话",........};
//        第一行
        Field[] declaredFields = orderCondition.getClass().getDeclaredFields();
        OutputStream out = null;
        try {
            //设置样式
            XSSFCellStyle cellStyle = wb.createCellStyle();
            cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            cellStyle.setFillForegroundColor(HSSFColor.ROYAL_BLUE.index);
            //第一行数据
            for (int i = 0; i < str.length; i++) {
                //填充背景颜色
                row.createCell(i).setCellStyle(cellStyle);
                row.getCell(i).setCellValue(str[i]);
            }
            //拿出所有的数据
            Iterator<OrderExcl> iterator = orders.iterator();
            //一条数据就是一行记录,开始起始的行号
            int index = 1;
            while (iterator.hasNext()) {
            //这个作用是为了记录需要合并的行的起始行
                int temp = index;
                OrderExcl order = iterator.next();
                List<Goods> goods = order.getGoods();
                int num = 0;
                if (null != goods && goods.size() > 0) {
                    num += goods.size();
                }
                //合并行的结束行号
                index += num;
                //获取所有的属/性名
                Class orderClass = order.getClass();
                Field[] fields = orderClass.getDeclaredFields();
              //以不需要合并行的个数,作为需要创建的行数
                for (int e = 0; e < num; e++) {
                    XSSFRow sheetRow = sheet.createRow(temp + e);
                    for (int i = 0; i < fields.length; i++) {
                    //填充不需要合并列的数据信息  start
                        if (i == 23) {
                            String name = goods.get(e).getShpMingCheng() == null ? "" : goods.get(e).getShpMingCheng();
                            sheetRow.createCell(24).setCellValue(name);
                            continue;
                        }
                        if (i == 24) {
                            String code = goods.get(e).getShpBianMa() == null ? "" : goods.get(e).getShpBianMa();
                            sheetRow.createCell(23).setCellValue(code);
                            continue;
                        }
                        if (i == 25) {
                            String weight = goods.get(e).getZhlKg() == null ? "" : goods.get(e).getZhlKg().toString();
                            sheetRow.createCell(25).setCellValue(weight);
                            continue;
                        }
        //填充不需要合并列的数据信息  end
                        //填充需要合并行的单元格的信息
                        XSSFCell cell = sheetRow.createCell(i);
                        //获取字段属性的值
                        String fieldName = fields[i].getName();
                        Object result = "";
                        //这里是你不需要合并的单元格里面需要填充的数据集合的名字
                        if (!fieldName.equals("goods")) {
                            result = getResult(order, fieldName);
                        }
                     
                        if (fieldName.equals("orderDate")) {
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                            result = result == null ? "" : simpleDateFormat.format((Date) result);
                        }
                
                        result = result == null ? "" : result.toString();

                        XSSFRichTextString richString = new XSSFRichTextString(result.toString());
                        cell.setCellValue(richString);
                    }
                    //合并单元格
                    if (e == num - 1) {
					/**
						23代表的意思是并不需要合并的列的   起始列号+ 1 ;
						比如:我的第 6列需要合并列的起始位置,则此处写  7
					*/
                        for (int j = 0; j < 23; j++) {
                            //行号   行号  列号  列号
                            sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
                        }
                        /**
                        29代表的意思是并不需要合并的列的   结束列号+ 1 ;
						比如:我的第 16列需要合并列的结束位置,则此处写 17
						*/
                        for (int j = 29; j < fields.length; j++) {
                            sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
                        }
                    }
                }//输出到本
				 try{地
						 OutputStream o = new FileOutputStream("D://2007.xlsx");
						 workbook.write(o);
					}catch (Exception e) {
				            e.printStackTrace();
				        } finally {
				            if (o!= null) {
				                o.close();
				            }
				        }
/**
     *反射 调用get方法,获取属性对应的值
     *
     * @param fieldName
     * @return
     */
    public Object getResult(OrderExcl order, String fieldName) {
        try {
            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            Class tCls = order.getClass();
            Method getMethod = tCls.getMethod(getMethodName, new Class[]{});
            Object value = getMethod.invoke(order, new Object[]{});
            return value;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

注意事项
保证实体类的字段和起始行的字段顺序一致,否则导出的显示顺序不一致

上面的方法实现了业务需要;献给大家借鉴;后面我会抽取一个工具类;方便大家直接使用;

========工具类

里面的枚举类,判断需要根据自己公司的枚举类修改取值即可

public class ExclUtils {


  
    /**
     * 不需要合并单元格的
     *
     * @param data        行数据的集合
     * @param heardStyle  开始行的单元格样式
     * @param otherStyle  除标题行的其他需要设置样式的单元格;key:属性名=字段名  value:填充的样式;
     * @param sheetName   sheet的名字
     * @param headers     标题行的数据信息
     * @param columnWidth 设置默认宽度
     * @param rowHeight   设置默认行高
     * @param dateFormat  日期格式化
     * @param <T>         行数据信息
     * @return
     * @throws IllegalAccessException
     */
    public static <T> XSSFWorkbook needNotMerge(List<T> data,
                                                XSSFCellStyle heardStyle,
                                                Map<String, XSSFCellStyle> otherStyle,
                                                String sheetName, String[] headers,
                                                Short columnWidth,
                                                Short rowHeight,
                                                String dateFormat
    ) throws IllegalAccessException, NoSuchFieldException {
        XSSFWorkbook wb = setDefaultConfig(sheetName,
                columnWidth, rowHeight, heardStyle, headers);
        XSSFSheet sheet = wb.getSheetAt(0);
        //填充数据行
        Iterator<T> iterator = data.iterator();
        int index = 0;
        if (null != headers) {
            index = 1;
        }
        while (iterator.hasNext()) {
            XSSFRow row = sheet.createRow(index);
            T next = iterator.next();
            Class<?> aClass = next.getClass();
            Field[] fields = aClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);
                Object value = field.get(next);
                if (null == value) {
                    value = "";
                }
                value = formatDataToString(dateFormat, value);
                if (null != otherStyle) {
                    boolean flag = otherStyle.containsKey(field.getName());
                    if (flag) {
                        row.createCell(i).setCellStyle(otherStyle.get(field.getName()));
                        row.getCell(i).setCellValue(value.toString());
                    }
                }
                row.createCell(i).setCellValue(value.toString());
            }
            index++;
        }
        return wb;
    }


    /**
     * @param data                  行数据的集合
     * @param heardStyle            头样式
     * @param otherStyle            其他行样式;key:属性值  value:样式
     * @param sheetName             sheet名字
     * @param headers               标题数组
     * @param columnWidth           单元格列宽
     * @param rowHeight             行高
     * @param needNotMergerColumNum 不需要合并的列的属性名,以及对应的列号;key:列号  value:属性名
     * @param dateFormat            日期格式
     * @param mergeName
     * @param <T>                   行数据对象
     * @param <E>                   不需要合并的单元格数据对象
     * @return
     */
    public static <T, E> XSSFWorkbook rowMerge(List<T> data,
                                               XSSFCellStyle heardStyle,
                                               Map<String, XSSFCellStyle> otherStyle,
                                               String sheetName,
                                               String[] headers,
                                               Short columnWidth,
                                               Short rowHeight,
                                               Map<Integer, String> needNotMergerColumNum,
                                               String dateFormat,
                                               Integer start,
                                               Integer end,
                                               String mergeName
    ) throws Exception {
        XSSFWorkbook wb = setDefaultConfig(sheetName, columnWidth,
                rowHeight, heardStyle, headers);
        XSSFSheet sheet = wb.getSheetAt(0);
        //填充数据行
        Iterator<T> iterator = data.iterator();
        int index = 0;
        if (null != headers) {
            index = 1;
        }
        while (iterator.hasNext()) {
            int temp = index;
            T next = iterator.next();
            Field mergeField = next.getClass().getDeclaredField(mergeName);
            mergeField.setAccessible(true);
            List<E> mergeData = (List<E>) mergeField.get(next);
            if (null == mergeData || mergeData.size() < 1) {
                Object o = new Object();
                E e = (E) o;
                mergeData.add(e);
            }
            index += mergeData.size();
            Field[] fields = next.getClass().getDeclaredFields();
            for (int i = 0; i < mergeData.size(); i++) {
                XSSFRow row = sheet.createRow(temp + i);
                for (int j = 0; j < fields.length; j++) {
                    Field field = fields[j];
                    field.setAccessible(true);
                    String fileName = field.getName();
                    XSSFCell cell = row.createCell(j);
                    if (null != otherStyle && otherStyle.containsKey(fileName)) {
                        cell.setCellStyle(otherStyle.get(fileName));
                    }
                    if (needNotMergerColumNum.containsKey(j)) {
                        String mergeFieldName = needNotMergerColumNum.get(j);
                        try {
                            Field mergeDeclaredField = mergeData.get(i).getClass().getDeclaredField(mergeFieldName);

                            mergeDeclaredField.setAccessible(true);
                            Object value = mergeDeclaredField.get(mergeData.get(i));
                            if (null == value) {
                                value = "";
                            }
                            value = formatDataToString(dateFormat, value);
                            cell.setCellValue(value.toString());
                            continue;
                        } catch (Exception e) {
                            cell.setCellValue("");
                            continue;
                        }
                    }
                    //获取属性字段的值
                    Object o = field.get(next);
                    if (null == o) {
                        o = "";
                    }
                    o = formatDataToString(dateFormat, o);
                    cell.setCellValue(o.toString());
                }
                //合并单元格
                if (i == mergeData.size() - 1) {
                    for (int j = 0; j < start; j++) {
                        //行号   行号  列号  列号
                        sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
                    }
                    for (int j = end; j < fields.length; j++) {
                        sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
                    }
                }
            }

        }
        return wb;
    }


    /**
     * excl的默认设置
     *
     * @param sheetName   sheet名字
     * @param columnWidth 列宽
     * @param rowHeight   行高
     * @param heardStyle  头样式
     * @param headers     标题行
     */
    private static XSSFWorkbook setDefaultConfig(String sheetName, Short columnWidth,
                                                 Short rowHeight, XSSFCellStyle heardStyle, String[] headers) {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet(sheetName);
        if (null != columnWidth) {
            sheet.setDefaultColumnWidth(columnWidth);
        } else {
            sheet.setDefaultColumnWidth((short) 20);
        }
        if (null != rowHeight) {
            sheet.setDefaultRowHeightInPoints(rowHeight);
        } else {
            sheet.setDefaultRowHeightInPoints(20);
        }
        if (null != headers) {  //创建标题行
            XSSFRow headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                if (null != heardStyle) {
                    headerRow.createCell(i).setCellStyle(heardStyle);
                    headerRow.getCell(i).setCellValue(headers[i]);
                } else {
                    headerRow.createCell(i).setCellValue(headers[i]);
                }
            }
        }
        return wb;
    }


    /**
     * 日期和枚举类转化为字符串
     *
     * @param dateFormat 日期格式,默认 yyyy-MM-dd HHLmm
     * @param value      需要转字符串的对象
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static String formatDataToString(String dateFormat, Object value) throws NoSuchFieldException, IllegalAccessException {
        if (null == value) {
            return "";
        }
        if (null == dateFormat) {
            dateFormat = "yyyy-MM-dd HH:mm";
        }
        if (value instanceof Date) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
            value = simpleDateFormat.format(value);
        }
        if (value instanceof IEnum) {
            Class<?> aClass = value.getClass();
            Field desc = aClass.getDeclaredField("desc");
            desc.setAccessible(true);
            value = desc.get(value);
            List list = new ArrayList();
            list.isEmpty();
        }
        return value.toString();
    }


}

最后

以上就是甜美芝麻为你收集整理的poi实现单元格行合并的全部内容,希望文章能够帮你解决poi实现单元格行合并所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部