精华内容
下载资源
问答
  • 目前的模式支持左侧,中间,右侧任意合并单元格,合并的是整个循环,如果循环是复杂数据结构,中间合并了少量单元格的话目前是不支持的 如果发现有什么bug或者有需求不满足也可以给我留言,有时间的话我会尽量处理 ...

    概述

    • excel比较常用的工具类就是poi和jxl当然后者已经停止维护很久而且只支持excel2003,不支持excel2007. 对2003版,最大行数是65536行 ,对2007以上版本,最大行数是1048576行.简单格式的数据导出jxl就够用了,但是复杂格式的数据则用excel模板较为方便
      
      <dependency>
          <groupId>net.sf.jxls</groupId>
          <artifactId>jxls-core</artifactId>
          <version>1.0.6</version>
      </dependency>
      后者也已经停止维护,最新的包是2014年的,不过相对于来说我更喜欢用后者,更方便,
      相对于前者不用配置作用域,包括循环等.前者是用注释的方式实现,我尝试使用的时候
      发现行中间的合并其不能做到(也许是我用的不对,总之就那样了),但是直接用代码操作
      合并单元格又过于繁琐,这也是当前开发的背景.
      同事使用时候遇到合并单元格的问题,合并的单元格不能解析数据也不能正确的合并
      如我下图的模板,合并了3行则生成出来的excel也只合并了3行,并且根据循环的数据量
      往下错位若干格,而且少一个边框,究其原因,原作者根本没处理循环内的合并单元格问题
      ,故此对1.0.6做了开发,修复这个问题,并将版本命名为2.0.传递到maven私服,pom为
      <dependency>
          <groupId>net.sf.jxls</groupId>
          <artifactId>jxls-core</artifactId>
          <version>2.0</version>
      </dependency>
    • 正文

    测试类如下

    import com.fasterxml.jackson.databind.exc.InvalidFormatException;
    import net.sf.jxls.exception.ParsePropertyException;
    import net.sf.jxls.transformer.XLSTransformer;
    import org.junit.Test;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.net.URLEncoder;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    /**
     * Created by admin on 2019/2/15.
     */
    public class JxlsExcelTest {
    
        public static void excelTest() throws IOException,
     org.apache.poi.openxml4j.exceptions.InvalidFormatException {
            //获得模版
            String tempFileName = Thread.currentThread().getContextClassLoader()
    .getResource("model/excelTemplate.xls").getFile();
            //将结果放入这个list中
            Date date = new Date();
            SimpleDateFormat simpl = new SimpleDateFormat("yyyyMMddHHmmss");
            String currntTime = simpl.format(date);
    
            //导出列表名
            String fileName = currntTime+"列表.xls";
            Map dataMap = new HashMap();
    
            List persionTypeList = new ArrayList();
            Map map1 = new HashMap();
            map1.put("personType", "初级");
            persionTypeList.add(map1);
    
            Map map2 = new HashMap();
            map2.put("personType", "中级");
            persionTypeList.add(map2);
    
            Map map3 = new HashMap();
            map3.put("personType", "高级");
            persionTypeList.add(map3);
    
            Map map4 = new HashMap();
            map4.put("personType", "高1级");
            persionTypeList.add(map4);
    
            dataMap.put("listData1", persionTypeList);
    
            List<Map<String,Object>> persionTypeList2=new 
    ArrayList<Map<String,Object>>();
            persionTypeList2.addAll(persionTypeList);
            persionTypeList2.remove(2);
            dataMap.put("listData2",persionTypeList2);
    
            List<Map<String,Object>> persionTypeList3=new 
    ArrayList<Map<String,Object>>();
            persionTypeList3.addAll(persionTypeList2);
            persionTypeList3.addAll(persionTypeList2);
            dataMap.put("listData3",persionTypeList3);
    
            dataMap.put("sum", "2012");
            dataMap.put("sum1", "2013");
            dataMap.put("sum2", "2014");
            dataMap.put("sum3", "2015");
            dataMap.put("sum4", "2016");
            dataMap.put("sum5", "2017");
    
            //生成的导出文件
            File destFile =new File("yyglxt/src/main/resources/model/"+fileName);
    
            //transformer转到Excel
            XLSTransformer transformer = new XLSTransformer();
    
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                System.out.println(destFile.getAbsolutePath());
                //将数据添加到模版中生成新的文件
                transformer.transformXLS(tempFileName, dataMap,
     destFile.getAbsolutePath());
            } catch (ParsePropertyException e) {
                e.printStackTrace();
            } catch (InvalidFormatException e) {
                e.printStackTrace();
            }finally {
                //使用完成后关闭流
                try {
                    if (bis != null)
                        bis.close();
                    if (bos != null)
                        bos.close();
                } catch (IOException e) {
                }
    
            }
        }
        public static void main(String[] args) throws Exception {
            excelTest();
        }
    }
    • excel模板如下

    • 最终生成的结果

    • 结束语

    目前的模式支持左侧,中间,右侧任意合并单元格,合并的是整个循环,如果循环是复杂数据结构,中间合并了少量单元格的话目前是不支持的

    如果发现有什么bug或者有需求不满足也可以给我留言,有时间的话我会尽量处理

    未经授权禁止转载,如果转载需要注明出处

    • 下载地址:

        jar包:jar包里已经包含了pom.xml,可以自行解压方便上传到maven私服,这种方式会带上依赖,否则要一个个手动添加依赖.pom在jar包里jxls-core\2.0\jxls-core-2.0\META-INF\maven\pom.xml,不过我也单独上传了一份,这个pom文件不需要下载,当然分多的豪如果不吝赞助,那就道一声多谢!

    如果现在不能下载,那是因为附件尚未过审核,需要等明天审核完毕了.

    上传maven私服的时候,可以直接上传以下的pom文件和jar包,这样的话不用自行添加依赖,否则依照pom

    文件人工添加依赖

    jar下载地址:   https://download.csdn.net/download/a1091662876/10965456

    pom下载地址(无须下载,jar里已经存在):https://download.csdn.net/download/a1091662876/10965540

     

     

    展开全文
  • 项目中有个需求,根据计划单号进行对应的单元格合并,还有对应的导出功能也是需要,前台使用的是bootstrap...}方法中进行实现合并单元格,注意,一定是其他操作完成之后再合并单元格,我的是有合计功能,刚开始是...

    项目中有个需求,根据计划单号进行对应的单元格合并,还有对应的导出功能也是需要,前台使用的是bootstrap插件,还好bootstrap有自己的合并功能。

    下面看下具体的实现

    一、前台bootstap实现动态合并单元格

    1.在onLoadSuccess : function(data) {

    }方法中进行实现合并单元格,注意,一定是其他操作完成之后再合并单元格,我的是有合计功能,刚开始是先合并再实现合计,结果合计功能一直出不来,很纳闷,试了一下更改顺序,结果就出来了,把整个的代码都贴一下吧

    function loadTable(flag) {
            if(flag=="1")
                {
                searchStr = $(".search__inp").val().trim();
                }
            var pageNumber = 1;
            $("#mainTable").bootstrapTable("destroy");
            var options = {
                pagination : true
                //, height: 400
                ,
                showFooter : false,
                paginationLoop : false
                //,sortable: true
                ,
                cache : false,
                pageNumber : pageNumber,
                pageSize : 10,
                pageList : [ 10],//[ 10, 20, 50 ],
                method : "get",
                contentType : 'application/x-www-form-urlencoded; charset=UTF-8',
                url : basePath + "student/productionReport/getReportList",
                queryParamsType : "",
                sidePagination : "server",
                queryParams : queryParamsMain,
                columns : [[
                        {
                            field : "id",
                            title : "序号",
                            align : "center",
                            valign : "middle",
                            colspan: 1,
                            rowspan: 2,
                            formatter : function(value, row, index) {
                            
                                //获取每页显示的数量
                                var pageSize = $('#mainTable').bootstrapTable(
                                        'getOptions').pageSize;
                                //获取当前是第几页  
                                var pageNumber = $('#mainTable').bootstrapTable(
                                        'getOptions').pageNumber;
                                //返回序号,注意index是从0开始的,所以要加上1
    
                                if (value == "total") {
                                    return "合计";
                                } else {
                                    return pageSize * (pageNumber - 1) + index + 1;
                                }
                            },
                            //width : 40
                        },
                        
                        
                        {
                            field : "planType",
                            title : "生产类型",
                            align : "center",
                            valign : "middle",
                            colspan: 1,
                            rowspan: 2,
                            formatter : function(value, row, index) {
                                var str="";
                                if(value==1)
                                    {
                                    str="内部生产";
                                    }
                                else if(value==2)
                                    {
                                    str="委托加工";
                                    }
                                return str;
                            },
                            //width : 68
                        },
    
                        {
                            field : "planCode",
                            title : "生产计划单号",
                            align : "center",
                            valign : "middle",
                            colspan: 1,
                            rowspan: 2,
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 58
                        },
    
                        {
                            //field : "code",
                            title : "生产信息",
                            align : "center",
                            valign : "middle",
                            colspan: 4,
                            rowspan: 1
                            //width : 145
                        },
                        {
                            //field : "code",
                            title : "用料明细",
                            align : "center",
                            valign : "middle",
                            colspan: 4,
                            rowspan: 1
                            //width : 145
                        },
                        {
                            field : "roundNo",
                            title : "轮次",
                            align : "center",
                            valign : "middle",
                            colspan: 1,
                            rowspan: 2,
                            //sortable: true,
                            formatter : function(value, row, index) {
                                if (value != "") {
                                    return "第" + value + "轮";
                                } else {
                                    return "";
                                }
     
                            },
    
                            //width : 46
                        } 
                        ],
                        [{
                            field : "productName",
                            title : "产品名称",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 67
                        },
                        {
                            field : "productCode",
                            title : "型料号",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 73
                        },
                        {
                            field : "actualQuantity",
                            title : "实际生产数量",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 28
                        },
    
                        {
                            field : "qualificationRate",
                            title : "合格率(%)",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 28
                        },
                        {
                            field : "bomType",
                            title : "产品类型",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                switch(value)
                                {
                                case 1:value="产成品";break;
                                case 2:value="半成品";break;
                                case 3:value="原材料";break;
                                }
                                return value;
                            },
                            //width : 53
                        },
                        {
                            field : "bomProductName",
                            title : "产品名称",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 86
                        },
                        {
                            field : "bomProductCode",
                            title : "型料号",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 190
                        },
                        {
                            field : "bomQuantity",
                            title : "生产实际用量",
                            align : "center",
                            valign : "middle",
                            formatter : function(value, row, index) {
                                return value;
                            },
                            //width : 65
                        }
                    ]],
                onLoadSuccess : function(data) {
                    
    
                    
                    var sum_1 = 0;
                    var sum_2 = 0;
                    var planCode="";
                    for ( var o in data.rows) {
                        if (!isNaN(o)) {
                            if(data.rows[o].planCode!=planCode)
                                {
                                if(!isNaN(data.rows[o].actualQuantity))
                                {
                                sum_1 = parseFloat(sum_1)+ parseFloat(data.rows[o].actualQuantity);
                                }
                                }
                            
                            sum_2 = parseFloat(sum_2)+ parseFloat(data.rows[o].bomQuantity);
                            planCode=data.rows[o].planCode;
                        }
    
                    }
                    if(data.rows.length>0)
                        {
                        var rows = [];
                        rows.push({
                            id : "total",
                            planType : "",
                            planCode : "",
                            productName : "",
                            productCode : "",
                            actualQuantity : sum_1,
                            qualificationRate : "",
                            bomType : "",
                            bomProductName : "",
                            bomProductCode : "",
                            bomQuantity : sum_2,
                            roundNo : ""
                        });
                        $('#mainTable').bootstrapTable('append', rows);
                        }
                        mergeCells(data.rows,"planCode", "planCode", 1, $('#mainTable'));
                        mergeCells(data.rows,"planCode", "actualQuantity", 1, $('#mainTable'));
                        mergeCells(data.rows,"planCode", "productName", 1, $('#mainTable'));
                        mergeCells(data.rows,"planCode", "productCode", 1, $('#mainTable'));
                        mergeCells(data.rows,"planCode", "qualificationRate", 1, $('#mainTable'));
    
                },
                responseHandler : function(data) {
                    return {
                        total : data.totalCount,
                        rows : data.result,
                    };
                },
                onPageChange : function(number, size) {
                    pageNumber = number;
                },
                onLoadError : function(textStatus, XMLHttpRequest) {
                }
            };
            $("#mainTable").bootstrapTable(options);
        }
        
    View Code

    2.具体的进行单元格合并,mergeCells可以实现单元格合并,此功能还是非常简单的

     1 /**
     2      * 合并单元格
     3      * @param data  原始数据(在服务端完成排序)
     4      * @param fieldName 合并属性名称
     5      * @param colspan   合并列
     6      * @param target    目标表格对象
     7      */
     8     function mergeCells(data,exhibitionName,fieldName,colspan,target){
     9         //声明一个map计算相同属性值在data对象出现的次数和
    10         var sortMap = {};
    11         for(var i = 0 ; i < data.length ; i++){
    12             for(var prop in data[i]){
    13                 if(prop == exhibitionName){
    14                     var key = data[i][prop];
    15                     if(sortMap.hasOwnProperty(key)){
    16                         sortMap[key] = sortMap[key] * 1 + 1;
    17                     } else {
    18                         sortMap[key] = 1;
    19                     }
    20                     break;
    21                 } 
    22             }
    23         }
    24         
    25         var index = 0;
    26         for(var prop in sortMap){
    27             var count = sortMap[prop] * 1;
    28             $("#mainTable").bootstrapTable('mergeCells',{index:index, field:fieldName, colspan: colspan, rowspan: count});   
    29             index += count;
    30         }
    31     }
    View Code

    二、导出excle中实现动态单元格合并

    1、在pom.xml中引入jar包

     1 <!-- exel导出依赖 -->
     2         <dependency>
     3             <groupId>net.sf.jxls</groupId>
     4             <artifactId>jxls-reader</artifactId>
     5             <version>0.9.9</version>
     6         </dependency>
     7         <dependency>
     8             <groupId>net.sf.jxls</groupId>
     9             <artifactId>jxls-core</artifactId>
    10             <version>0.9.9</version>
    11         </dependency>
    12         <dependency>
    13             <groupId>jexcelapi</groupId>
    14             <artifactId>jxl</artifactId>
    15             <version>2.4.2</version>
    16         </dependency>
    View Code

    2、业务功能实现,

    3、导出方法(合并单元格),含有非合并的代码

    List<Merge> ml = getMerge(list, "getPlanCode");这个是合并的关键字

    // 起始行号,终止行号, 起始列号,终止列号
    sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 3, m.getToRow() +3, 3, 3));这个进行具体的合并,从网上找的帖子,用的反射降低耦合度,其实可以不用反射,直接用对应功能实现

      1 package com.gta.scm.component.common.utils;
      2 
      3 /**
      4  * 
      5  */
      6 
      7 
      8 import java.io.BufferedInputStream;
      9 import java.io.ByteArrayOutputStream;
     10 import java.io.FileInputStream;
     11 import java.io.FileNotFoundException;
     12 import java.io.IOException;
     13 import java.io.InputStream;
     14 import java.io.OutputStream;
     15 import java.io.UnsupportedEncodingException;
     16 import java.lang.reflect.InvocationTargetException;
     17 import java.util.ArrayList;
     18 import java.util.HashMap;
     19 import java.util.List;
     20 import java.util.Map;
     21 import javax.servlet.ServletOutputStream;
     22 import javax.servlet.http.HttpServletRequest;
     23 import javax.servlet.http.HttpServletResponse;
     24 
     25 import net.sf.jxls.exception.ParsePropertyException;
     26 import net.sf.jxls.transformer.XLSTransformer;
     27 import org.apache.commons.codec.binary.Base64;
     28 import org.apache.poi.hssf.usermodel.HSSFSheet;
     29 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
     30 import org.apache.poi.ss.util.CellRangeAddress;
     31 import org.slf4j.Logger;
     32 import org.slf4j.LoggerFactory;
     33 
     34 import com.fasterxml.jackson.databind.exc.InvalidFormatException;
     35 import com.gta.scm.common.entity.Merge;
     36 
     37 
     38 /**
     39  * @author jingshu.deng
     40  *
     41  */
     42 public class FileUtils {
     43     private static Logger logger = LoggerFactory.getLogger(FileUtils.class);
     44 
     45     /**
     46      * @param fileName
     47      * @return
     48      */
     49     public static String getFileExtension(String fileName) {
     50         if (StringUtils.isEmpty(fileName)) {
     51             return StringUtils.EMPTY;
     52         }
     53 
     54         return StringUtils.substringAfter(fileName, ".");
     55     }
     56 
     57     /**
     58      * 
     59      * 解决文件下载时文件名的中文乱码及Firefox下空格被截断的问题
     60      * 
     61      * @param request
     62      * @param fileName
     63      * @return
     64      */
     65     public static String decodeFileName(HttpServletRequest request,    String fileName) {
     66         String agent = (String) request.getHeader(CharEncodingCons.USER_AGENT);
     67         try {
     68             // check whether Firefox according to USER-AGENT
     69             // 增加条件 agent.indexOf("Trident") == -1 针对IE10以上
     70             if (agent != null && agent.indexOf(CharEncodingCons.BROWSER_IE) == -1 && agent.indexOf("Trident") == -1) {
     71                 byte[] bytes = Base64.encodeBase64(fileName.getBytes(CharEncodingCons.HTTP_CHARSET));
     72                 fileName = new String(bytes, CharEncodingCons.HTTP_CHARSET);
     73                 fileName = "=?" + CharEncodingCons.HTTP_CHARSET + "?B?" + fileName + "?=";
     74             } 
     75             else {
     76                 byte[] bytes = fileName.getBytes(CharEncodingCons.DOWNLOAD_CHARSET);
     77                 fileName = new String(bytes, CharEncodingCons.WEB_CHARSET);
     78             }
     79         } 
     80         catch (UnsupportedEncodingException e) {
     81             logger.error("UnsupportedEncodingException occurs while flushing file", e);
     82         }
     83         return fileName;
     84     }
     85     
     86     /**
     87      * 导出Excel文件,按模板方式
     88      * @param response
     89      * @param templateName 模板名称及完全路径
     90      * @param map 
     91      * @param fileName 要导出的文件名
     92      */
     93     public static void exportXlsFile(HttpServletRequest request,HttpServletResponse response,String templateName,Map<String,Object> map,String fileName){
     94         try
     95         {
     96             XLSTransformer transformer=new XLSTransformer();
     97             //XLSTransformer transformer = new XLSTransformer();    
     98             InputStream in = new BufferedInputStream(new FileInputStream(templateName),25000);
     99             HSSFWorkbook workbook = transformer.transformXLS(in, map);
    100             //write to buffer
    101             ByteArrayOutputStream buf = new ByteArrayOutputStream(40000);
    102             workbook.write(buf);
    103             // write to response
    104             in.close();
    105             response.setContentType("application/vnd.ms-excel");
    106             response.setHeader("Content-disposition", "attachment; filename=" + decodeFileName(request,fileName)); 
    107             ServletOutputStream out = response.getOutputStream();
    108             out.write(buf.toByteArray());
    109             out.flush();
    110             out.close();
    111         }catch (IOException e){
    112             e.printStackTrace();
    113         }
    114     }
    115     
    116     // 先用String
    117         public static <T> Object useMethod(T t, String sx) throws IllegalAccessException, IllegalArgumentException,
    118                 InvocationTargetException, NoSuchMethodException, SecurityException {
    119             // 一般传入get方法
    120             return (Object) t.getClass().getMethod(sx, null).invoke(t, null);
    121 
    122         }
    123 
    124         public static <T> List<Merge> getMerge(List<T> list, String sx) throws IllegalAccessException,
    125                 IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
    126             // 可以传入 想合并的属性值 传入一个字符串 用反射找到相应的get方法 指定调用此方法。。这里先写死
    127             List<Merge> ml = new ArrayList<Merge>();
    128             for (int i = 0; i < list.size() - 1; i++) {
    129                 if (useMethod(list.get(i), sx).equals(useMethod(list.get(i + 1), sx))) {
    130                     Object property = useMethod(list.get(i), sx);
    131                     logger.debug("property"+property);
    132                     Merge merge = new Merge();
    133                     int fromRow = i, toRow = i + 1;
    134                     if (i + 2 < list.size()) {
    135                         for (int j = i + 2; j < list.size(); j++) {
    136                             if (useMethod(list.get(j), sx).equals(property) ) {
    137                                 toRow++;
    138                             } else {
    139                                 i = j - 1;
    140                                 break;
    141                             }
    142                         }
    143                     }
    144                     merge.setFromRow(fromRow);
    145                     merge.setToRow(toRow);
    146                     ml.add(merge);
    147                 }
    148             }
    149             return ml;
    150         }
    151         
    152         public static <T> void exportXlsFileMerge(HttpServletRequest request,HttpServletResponse response,String templateName,List<T> list,Map<String,Object> map,String fileName)
    153                 throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
    154                 SecurityException, FileNotFoundException, ParsePropertyException, InvalidFormatException {
    155             String templateFile = fileName;
    156             Map<String, Object> beans = new HashMap<String, Object>();
    157             InputStream in = new FileInputStream(templateName);
    158     
    159             XLSTransformer transformer = new XLSTransformer();
    160 
    161             HSSFWorkbook workBook = (HSSFWorkbook) transformer.transformXLS(in, map); // 传入模板的输入流和map
    162             // 开始进行合并单元格
    163             HSSFSheet sheet = workBook.getSheetAt(0);// 1 1
    164             List<Merge> ml = getMerge(list, "getPlanCode");
    165             for (Merge m : ml) {
    166                 // 起始行号,终止行号, 起始列号,终止列号
    167                 sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 3, m.getToRow() +3, 3, 3));
    168                 sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 3, m.getToRow() +3, 4, 4));
    169                 sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 3, m.getToRow() +3, 5, 5));
    170                 sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 3, m.getToRow() +3, 6, 6));
    171                 sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 3, m.getToRow() +3, 2, 2));
    172             }
    173             try {
    174                 
    175                 ByteArrayOutputStream buf = new ByteArrayOutputStream(40000);
    176                 workBook.write(buf);
    177                 // write to response
    178                 in.close();
    179                 response.setContentType("application/vnd.ms-excel");
    180                 response.setHeader("Content-disposition", "attachment; filename=" + decodeFileName(request,fileName)); 
    181                 ServletOutputStream out = response.getOutputStream();
    182                 out.write(buf.toByteArray());
    183                 out.flush();
    184                 out.close();
    185                 
    186                 
    187             } catch (IOException ie) {
    188                 ie.printStackTrace();
    189             } catch (ParsePropertyException e) {
    190                 // TODO Auto-generated catch block
    191                 e.printStackTrace();
    192             }
    193 
    194         }
    195 
    196 }
    View Code

     

    添加merge类进行记录行号
     1 public class Merge {
     2     private int fromRow;
     3     private int toRow;
     4     private int fromIndex;
     5     private int toIndex;
     6     public int getFromRow() {
     7         return fromRow;
     8     }
     9     public void setFromRow(int fromRow) {
    10         this.fromRow = fromRow;
    11     }
    12     public int getToRow() {
    13         return toRow;
    14     }
    15     public void setToRow(int toRow) {
    16         this.toRow = toRow;
    17     }
    18     public int getFromIndex() {
    19         return fromIndex;
    20     }
    21     public void setFromIndex(int fromIndex) {
    22         this.fromIndex = fromIndex;
    23     }
    24     public int getToIndex() {
    25         return toIndex;
    26     }
    27     public void setToIndex(int toIndex) {
    28         this.toIndex = toIndex;
    29     }
    30     
    31 }
    View Code

    调用的地方需要特别注意的地方

    String templateFileName = request.getServletContext().getRealPath("/")
    + "/reportTemplate//ProductionReportTemplate.xls";
    String destFileName = "生产产品明细汇总表.xls";

    map.put("productionReportList", productionReport);

    4.exlce模板

    5.导出结果

     

     哈,这样前后台都进行了实现了

    转载于:https://www.cnblogs.com/songStar/p/10956483.html

    展开全文
  • jxls动态合并单元格

    千次阅读 2017-04-28 13:14:00
    // 开始进行合并单元格 HSSFSheet sheet = workBook.getSheetAt(0);// 1 1 List<Merge> ml = getMerge(gen(), "getName"); for (Merge m : ml) { // 因为知道是第一列 的合并 所以写死 行+1是因为 第一行...

    在研究jxls时  想生成的模板  和传入的javabean 怎么样才可以做到 动态合并 相邻行的同一信息的单元格

    比如  

    王五	  1                                王五       1
    王五	  2            合并成:                    2
    王刘	   3                               王刘        3
    

    看了很多博客 再结合自己的研究 和文档 发现 只能通过 先生成 没有合并过的输出流 转成 工作薄对象 再进行加工 从而 输出 思路为:先得到要传入到模板上的list 设置想要 合并的字段名 比如name (当然 这个list得要是后台按groupby 传来有顺序的。。毕竟 我的程序还是比较年幼) 找出相同名字的 起始位置 用poi进行单元格合并

    首先 写了两个实体 1.为了模拟测试 的student类

    package workdemo.entity;
    
    public class Student {
    	private String name;
    	private String subject;
    	private int score;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getSubject() {
    		return subject;
    	}
    
    	public void setSubject(String subject) {
    		this.subject = subject;
    	}
    
    	public int getScore() {
    		return score;
    	}
    
    	public void setScore(int score) {
    		this.score = score;
    	}
    
    	public Student(String name, String subject, int score) {
    		super();
    		this.name = name;
    		this.subject = subject;
    		this.score = score;
    	}
    
    }
    
    

    2.为了方便记录起始位置 我写了一个类

    package workdemo.entity;
    
    public class Merge {
    	private int fromRow;
    	private int toRow;
    	private int fromIndex;
    	private int toIndex;
    
    	public int getFromRow() {
    		return fromRow;
    	}
    
    	public void setFromRow(int fromRow) {
    		this.fromRow = fromRow;
    	}
    
    	public int getToRow() {
    		return toRow;
    	}
    
    	@Override
    	public String toString() {
    		return "Merge [fromRow=" + fromRow + ", toRow=" + toRow + ", fromIndex=" + fromIndex + ", toIndex=" + toIndex
    				+ "]";
    	}
    
    	public void setToRow(int toRow) {
    		this.toRow = toRow;
    	}
    
    	public int getFromIndex() {
    		return fromIndex;
    	}
    
    	public void setFromIndex(int fromIndex) {
    		this.fromIndex = fromIndex;
    	}
    
    	public int getToIndex() {
    		return toIndex;
    	}
    
    	public void setToIndex(int toIndex) {
    		this.toIndex = toIndex;
    	}
    }
    
    

    3.主函数 基于反射写了个方法 降低耦合度

    package com.icom.util.base.test;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.lang.reflect.InvocationTargetException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.CellRangeAddress;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    
    import com.icom.util.base.test.entity.Merge;
    import com.icom.util.base.test.entity.Student;
    
    import net.sf.jxls.exception.ParsePropertyException;
    import net.sf.jxls.transformer.XLSTransformer;
    
    public class Main {
    	public static List<Student> gen() {
    		// 模拟生成 一个学生list 经过排列 特意有几个是同一个学生考的
    		List<Student> list = new ArrayList<Student>();
    		for (int i = 50; i < 55; i++) {
    			list.add(new Student("吴承接", "数学", i));
    		}
    		list.add(new Student("多大的", "物理", 55));
    		list.add(new Student("多大的", "化学", 99));
    		list.add(new Student("多大的", "信息", 56));
    		list.add(new Student("呵呵", "物理", 55));
    		list.add(new Student("蛋蛋", "物理", 55));
    		list.add(new Student("蛋蛋", "物无", 55));
    		list.add(new Student("鸡儿", "物理", 55));
    		return list;
    	}
    
    	// 先用String
    	public static <T> Object useMethod(T t, String sx) throws IllegalAccessException, IllegalArgumentException,
    			InvocationTargetException, NoSuchMethodException, SecurityException {
    		// 一般传入get方法
    		return (Object) t.getClass().getMethod(sx, null).invoke(t, null);
    
    	}
    
    	public static <T> List<Merge> getMerge(List<T> list, String sx) throws IllegalAccessException,
    			IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
    		// 可以传入 想合并的属性值 传入一个字符串 用反射找到相应的get方法 指定调用此方法。。这里先写死
    		List<Merge> ml = new ArrayList<Merge>();
    		for (int i = 0; i < list.size() - 1; i++) {
    			if (useMethod(list.get(i), sx) == useMethod(list.get(i + 1), sx)) {
    				Object property = useMethod(list.get(i), sx);
    				// System.out.println(property);
    				// System.out.println("第" + (i + 1) + "个和第" + i + "个一样");
    				Merge merge = new Merge();
    				int fromRow = i, toRow = i + 1;
    				if (i + 2 < list.size()) {
    					for (int j = i + 2; j < list.size(); j++) {
    						if (useMethod(list.get(j), sx) == property) {
    							toRow++;
    						} else {
    							i = j - 1;
    							break;
    						}
    					}
    				}
    				merge.setFromRow(fromRow);
    				merge.setToRow(toRow);
    				ml.add(merge);
    			}
    		}
    		return ml;
    	}
    
    
    	public static void main(String[] args)
    			throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
    			SecurityException, FileNotFoundException, ParsePropertyException, InvalidFormatException {
    		String templateFile = "d://test//mergedemo.xls";
    		Map<String, Object> beans = new HashMap<String, Object>();
    		InputStream is = new FileInputStream(templateFile);
    		List<Student> data = gen();
    		beans.put("data", data);
    		XLSTransformer transformer = new XLSTransformer();
    		HSSFWorkbook workBook = (HSSFWorkbook) transformer.transformXLS(is, beans); // 传入模板的输入流和map
    		// 开始进行合并单元格
    		HSSFSheet sheet = workBook.getSheetAt(0);// 1 1
    		List<Merge> ml = getMerge(gen(), "getName");
    		for (Merge m : ml) {
    			// 因为知道是第一列 的合并 所以写死 行+1是因为 第一行是列名
    			sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 1, m.getToRow() + 1, 0, 0));
    		}
    		try {
    			OutputStream os = new FileOutputStream("d://test//mergeResult.xls");
    			workBook.write(os);
    			is.close();
    			os.flush();
    			os.close();
    		} catch (IOException ie) {
    			ie.printStackTrace();
    		} catch (ParsePropertyException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
    	}
    }
    

    4.excle 模板
    输入图片说明

    5.输出结果:

    输入图片说明

    最后就可以得到 装有Merge对象的list 循环list 就可以调用 poi里的 addMergedRegion( CellRangeAddress cellRangeAddress ) 进行合并

    还是蛮有收获的。。。。。。复习了反射~

    转载于:https://my.oschina.net/xlpapapa/blog/889071

    展开全文
  • jxls2.0支持合并单元格

    2019-02-19 19:04:20
    jxls2.0支持合并单元格合并单元格模板写入数据,jar包里已经包含了pom.xml,可以自行解压方便上传到maven私服,这种方式会带上依赖,否则要一个个手动添加依赖.pom在jar包里jxls-core\2.0\jxls-core-2.0\META-INF\...
  • 在研究jxls时 想生成的模板 和传入的javabean 怎么样才可以做到 动态合并 相邻行的同一信息的单元格比如王五 1 王五 1王五 2 合并成: 2王刘 3 王刘 3看了很多...

    在研究jxls时  想生成的模板  和传入的javabean 怎么样才可以做到 动态合并 相邻行的同一信息的单元格

    比如

    王五 1 王五 1

    王五 2 合并成: 2

    王刘 3 王刘 3

    看了很多博客 再结合自己的研究 和文档 发现 只能通过 先生成 没有合并过的输出流 转成 工作薄对象 再进行加工 从而 输出 思路为:先得到要传入到模板上的list 设置想要 合并的字段名 比如name (当然 这个list得要是后台按groupby 传来有顺序的。。毕竟 我的程序还是比较年幼) 找出相同名字的 起始位置 用poi进行单元格合并

    首先 写了两个实体 1.为了模拟测试 的student类

    package workdemo.entity;

    public class Student {

    private String name;

    private String subject;

    private int score;

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    public String getSubject() {

    return subject;

    }

    public void setSubject(String subject) {

    this.subject = subject;

    }

    public int getScore() {

    return score;

    }

    public void setScore(int score) {

    this.score = score;

    }

    public Student(String name, String subject, int score) {

    super();

    this.name = name;

    this.subject = subject;

    this.score = score;

    }

    }

    2.为了方便记录起始位置 我写了一个类

    package workdemo.entity;

    public class Merge {

    private int fromRow;

    private int toRow;

    private int fromIndex;

    private int toIndex;

    public int getFromRow() {

    return fromRow;

    }

    public void setFromRow(int fromRow) {

    this.fromRow = fromRow;

    }

    public int getToRow() {

    return toRow;

    }

    @Override

    public String toString() {

    return "Merge [fromRow=" + fromRow + ", toRow=" + toRow + ", fromIndex=" + fromIndex + ", toIndex=" + toIndex

    + "]";

    }

    public void setToRow(int toRow) {

    this.toRow = toRow;

    }

    public int getFromIndex() {

    return fromIndex;

    }

    public void setFromIndex(int fromIndex) {

    this.fromIndex = fromIndex;

    }

    public int getToIndex() {

    return toIndex;

    }

    public void setToIndex(int toIndex) {

    this.toIndex = toIndex;

    }

    }

    3.主函数 基于反射写了个方法 降低耦合度

    package com.icom.util.base.test;

    import java.io.FileInputStream;

    import java.io.FileNotFoundException;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.InputStream;

    import java.io.OutputStream;

    import java.lang.reflect.InvocationTargetException;

    import java.util.ArrayList;

    import java.util.HashMap;

    import java.util.List;

    import java.util.Map;

    import org.apache.poi.hssf.usermodel.HSSFSheet;

    import org.apache.poi.hssf.usermodel.HSSFWorkbook;

    import org.apache.poi.hssf.util.CellRangeAddress;

    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

    import com.icom.util.base.test.entity.Merge;

    import com.icom.util.base.test.entity.Student;

    import net.sf.jxls.exception.ParsePropertyException;

    import net.sf.jxls.transformer.XLSTransformer;

    public class Main {

    public static List gen() {

    // 模拟生成 一个学生list 经过排列 特意有几个是同一个学生考的

    List list = new ArrayList();

    for (int i = 50; i < 55; i++) {

    list.add(new Student("吴承接", "数学", i));

    }

    list.add(new Student("多大的", "物理", 55));

    list.add(new Student("多大的", "化学", 99));

    list.add(new Student("多大的", "信息", 56));

    list.add(new Student("呵呵", "物理", 55));

    list.add(new Student("蛋蛋", "物理", 55));

    list.add(new Student("蛋蛋", "物无", 55));

    list.add(new Student("鸡儿", "物理", 55));

    return list;

    }

    // 先用String

    public static Object useMethod(T t, String sx) throws IllegalAccessException, IllegalArgumentException,

    InvocationTargetException, NoSuchMethodException, SecurityException {

    // 一般传入get方法

    return (Object) t.getClass().getMethod(sx, null).invoke(t, null);

    }

    public static List getMerge(List list, String sx) throws IllegalAccessException,

    IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {

    // 可以传入 想合并的属性值 传入一个字符串 用反射找到相应的get方法 指定调用此方法。。这里先写死

    List ml = new ArrayList();

    for (int i = 0; i < list.size() - 1; i++) {

    if (useMethod(list.get(i), sx) == useMethod(list.get(i + 1), sx)) {

    Object property = useMethod(list.get(i), sx);

    // System.out.println(property);

    // System.out.println("第" + (i + 1) + "个和第" + i + "个一样");

    Merge merge = new Merge();

    int fromRow = i, toRow = i + 1;

    if (i + 2 < list.size()) {

    for (int j = i + 2; j < list.size(); j++) {

    if (useMethod(list.get(j), sx) == property) {

    toRow++;

    } else {

    i = j - 1;

    break;

    }

    }

    }

    merge.setFromRow(fromRow);

    merge.setToRow(toRow);

    ml.add(merge);

    }

    }

    return ml;

    }

    public static void main(String[] args)

    throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,

    SecurityException, FileNotFoundException, ParsePropertyException, InvalidFormatException {

    String templateFile = "d://test//mergedemo.xls";

    Map beans = new HashMap();

    InputStream is = new FileInputStream(templateFile);

    List data = gen();

    beans.put("data", data);

    XLSTransformer transformer = new XLSTransformer();

    HSSFWorkbook workBook = (HSSFWorkbook) transformer.transformXLS(is, beans); // 传入模板的输入流和map

    // 开始进行合并单元格

    HSSFSheet sheet = workBook.getSheetAt(0);// 1 1

    List ml = getMerge(gen(), "getName");

    for (Merge m : ml) {

    // 因为知道是第一列 的合并 所以写死 行+1是因为 第一行是列名

    sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 1, m.getToRow() + 1, 0, 0));

    }

    try {

    OutputStream os = new FileOutputStream("d://test//mergeResult.xls");

    workBook.write(os);

    is.close();

    os.flush();

    os.close();

    } catch (IOException ie) {

    ie.printStackTrace();

    } catch (ParsePropertyException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

    4.excle 模板

    4c2143d73da70d1188c668b68ba049e5.png

    5.输出结果:

    701e3d483ae6acbe2532d34920a8da6b.png

    最后就可以得到 装有Merge对象的list 循环list 就可以调用 poi里的 addMergedRegion( CellRangeAddress cellRangeAddress ) 进行合并

    还是蛮有收获的。。。。。。复习了反射~

    展开全文
  • 想要的功能是 row里面的数据,根据 row.items 数据合并单元格,现在只能是每行都全部数据,就导致了很多的重复单元格数据 看了下其他人写的文档也没有完全看明白?有没有大佬可以直接给个DEMO 另外, 这个方法,...
  • jxls2 动态合并单元格指令

    千次阅读 2018-10-19 09:51:42
    将merge指令的代码注册到jxls的指令集里 代码传送门:https://gitee.com/lnkToKing/jxlss/blob/master/src/main/java/pres/lnk/jxlss/command/MergeCommand.java 注册代码: XlsCommentAreaBuilder....
  • //合并 } } } //第二列 if (Empty.isNotEmpty(arrname)) { List list1 = Lists.newArrayList(Ints.asList(arrname)); for (int i = 0; i (); i++) { int a = list1.get(i); if (a > 0) {//如果大于0 sheet....
  • 无须下载,jar包里已经包含了,自行解压即可.积分多的想省事的自便,谢谢赞助 :) 这里的这个只是jar包里的pom,只下载pom是不行的,jar包是修改过的 所以如果要用jar,要用下面的地址,如果遇到什么问题,可随时联系我 ...
  • http://www.chendd.cn/information/viewInformation/other/235.a本章节将在导出逻辑中演示使用Jxls2时在模板实现单元格合并...之前在Jxls1的时候也都是使用它生产报表Excel文件,再使用Poi二次去实现单元格合并的逻...
  • JXLS部分的合并单元格错误解决办法

    千次阅读 2014-10-16 13:23:32
    由XLSTransformer类的方法: transformMultipleSheetsList(is,objects,newSheetNames,beanName,beanParams,startSheetNum;... 在Workbook输出之前调用以下方法,可以去除重复的单元格合并  //去除重复的单元格
  • <groupId>org.jxls <artifactId>jxls <version>2.6.0 <groupId>org.jxls <artifactId>jxls-poi <version>1.2.0 <groupId>org.apache.commons <artifactId>commons-jexl <version>2.1.1 ...
  • 本章节将在导出逻辑中演示使用Jxls2时在模板实现单元格合并的效果。实际上官网上提供的单元格合并并非为我们所需要的实际效果,而是使用循环嵌套的方式来进行数据展示...
  • // 合并单元格 int alreayUseCol = 0; int m = 1; int otherSize; CellRangeAddress region; for (ClientAccountResp rsp : re) { // 取最长列 otherSize = rsp.getOtherDetail().size(); if (otherSize ) { m++; ...
  • java将数据导出,带有合并单元格的excel--jxls技术

    万次阅读 热门讨论 2017-03-09 11:40:04
    说起用这个还是比较有意思的,当时项目有个导出表格的功能,但是没能合并单元格,客户不是很满意,当时项目中大家都说弄不了,我想着自己网上查查吧,就查到了这个,试了一下午完成了,很有成就感哪,哈哈。...
  • 合并单元格

    2020-08-31 11:37:59
    package com.ssh.hygiene.controller; import ... ... import org.jxls.area.Area; import org.jxls.builder.AreaBuilder;...import org.jxls.builder.xls.XlsCommentAreaBuilder;...import org.jxls.common.
  • demo包含全部官方例子和模版, 2.6官方新增合并单元格标签,jx:mergecells 以及其他相关一切demo,很好的资源,分享给大家,供大家学习交流。 环境依赖 maven JDK1.8 不管使用eclipse 或者idea 直接导入即可,项目中...
  • 文档 :http://jxls.sourceforge.net/ ... var is a name of the variable in Jxls context to put each new collection item when iterating items is a name of a context variable containing the collection
  • 可以看到代码中指定合并的部分现在已经显示出了效果。 模板 [java] view plain copy List supplyAreaList = saBiz.getSupplyAreaById(supplyAreaId);   SupplyArea sa = ...
  • 员工姓名没有自动合并单元格,在http://jxls.sourceforge.net/reference/xls_area.html 上面找了半天没有相关的案例,于是就自己代码生成2.动态生成excel文件,并动态合并单元格package ...

空空如也

空空如也

1 2 3
收藏数 49
精华内容 19
关键字:

jxls合并单元格