关于poi word 文档生成的那些坑坑洼洼

产品需求

近期产品提了一个需求,要求我们将查询出来的数据以表格的形式保存在excel和word文档中,excel的单元格有强大的适应性和扩展性,基本无难度,但是word,嗯,要兼容wps word和Microsoft Word,一言难尽。

	/**
     * 导出word文件
     */
    public static XWPFDocument createXWPFDocument(List<Map<String, Object>> data,List<String> fileds) throws Exception {
    	//创建word文档
        XWPFDocument doc = new XWPFDocument();
        //创建表头
        createTitleParagraph(doc);
        //写入数据
        if(CollectionUtils.isNotEmpty(data)){
            createCell(doc, data,fileds);
        }
        //返回文档
        return doc;
    }

    /**
     * 创建表格的样式标题
     *
     * @param document
     */
    public static void createTitleParagraph(XWPFDocument document) {
        //新建一个标题段落对象(就是一段文字)
        XWPFParagraph titleParagraph = document.createParagraph();
        //样式居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        //创建文本对象
        XWPFRun titleFun = titleParagraph.createRun();
        //设置标题的名字
        titleFun.setText("报告报表word文档导出");
        //加粗
        titleFun.setBold(true);
        //设置颜色
        titleFun.setColor("000000");
        //字体大小
        titleFun.setFontSize(20);
        //设置字体
        titleFun.setFontFamily("Courier");
        //换行
        titleFun.addBreak();
    }

    /**
     * 创建单元格并存储数据
     *
     * @param document
     */
    public static void createCell(XWPFDocument document, List<Map<String, Object>> data,List<String> fileds) {
        XWPFTable infoTable = document.createTable();
        //设置单元格表头,这个地方是做了一个汉化表头的处理
        List<String> assetHeadTemp = getAssetHeadTemp(fileds);
 		//设置单元格内字体大小,因为产品需求最多有10列,为了让字体正常显示,所以对字体大小调节
        int fontSize = 0;
        if(assetHeadTemp.size()>5){
           fontSize = 7;
        }else {
            fontSize = 10;
        }
        //获取每列的列宽
        long columnWidth  = new Double(Math.floor(8000/assetHeadTemp.size())).longValue();
        //遍历要添加的数据的list
        for (int i = 0; i <= data.size() ; i++) {
            //为表格添加行
            XWPFTableRow newRow = infoTable.insertNewTableRow(i + 1);
            //遍历list中的字符串数组
            for (int j = 0; j < assetHeadTemp.size(); j++) {
                //在新增的行上面创建cell,并设置对齐方式为居中
                newRow.createCell().setVerticalAlignment(XWPFTableCell.XWPFVertAlign.BOTH);
                //设置单元格样= 式
                XWPFTableCell cell = newRow.getCell(j);
//                //设置单元格宽度
                CTTcPr tcpr = cell.getCTTc().addNewTcPr();
                CTTblWidth cellW = tcpr.addNewTcW();
                cellW.setType(STTblWidth.DXA);
                cellW.setW(BigInteger.valueOf(columnWidth));

                //创建段落对象
                XWPFParagraph p=cell.addParagraph();
                //创建文本对象
                XWPFRun run = p.createRun();
				//可以换行,可以换行,可以换行,重要的事情说三遍,这个地方很重要
                run.addBreak();
                if (i == 0) {
                    run.setText(assetHeadTemp.get(j));
                }else {
                    Map<String, Object> map = data.get(i - 1);
                    String key = fileds.get(j);
                    if (map.get(key) == null) {
                        //给每个cell赋值。
                        run.setText("");
                    } else {
                        run.setText(key.equals(DIMENSION_PREFIX+"_cw_raw_time")?DateUtil.convertTimeToString(Long.parseLong(map.get(key).toString())):map.get(key).toString());
                    }
                }
                run.setFontSize(fontSize);
            }
        }
        //删除第一空白行
        infoTable.removeRow(0);
        //写完数据后调整单元格样式
        //设置表格宽
        CTTbl table = infoTable.getCTTbl();
        CTTblPr pr = table.getTblPr();
        CTTblWidth tblW = pr.getTblW();
        tblW.setW(BigInteger.valueOf(8000));
        tblW.setType(STTblWidth.DXA);
        pr.setTblW(tblW);
        table.setTblPr(pr);
        CTJc jc = pr.addNewJc();
        jc.setVal(STJc.LEFT);
        pr.setJc(jc);
        //使布局固定,不随内容改变宽度,这个非常非常非常重要,如果不固定布局,一个单元格里边的字符长度成百上千的时候,单元格就会放飞自我,就像下边的例图一样,惨不忍睹。另附一张加上下边固定布局之后的代码格式。。
        CTTblLayoutType t = pr.isSetTblLayout()?pr.getTblLayout():pr.addNewTblLayout();
        t.setType(STTblLayoutType.FIXED);
    }
	/**
     * 翻译表头信息
     * @return
     */
    private static  List<String> getAssetHeadTemp(List<String> fileds){
        List<String> assetHeadTemp = new ArrayList<>();
        fileds.forEach(field->{
            if(field.startsWith(DIMENSION_PREFIX)){
                assetHeadTemp.add(LogFieldsEnum.getChinese(field.replace(DIMENSION_PREFIX,""))+"(聚合维度)");
            } else {
                assetHeadTemp.add(LogFieldsEnum.getChinese(field));
            }
        });
        System.out.println("获得的表头信息是:"+assetHeadTemp);
        return assetHeadTemp;
    }

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值