weixin_39878989
weixin_39878989
2020-11-28 14:22

图片处理问题,compile.render(model)丢失图片

1.8.1版本:使用区块对进行写入,之前写入文字一切正常,现在添加图片标签,多张图片render方法随机丢失,没有规律,6张图片只出2张。 模板内容: {{?sections}} {{title}}{{precontent}} {{}}{{}}{{}}{{}}{{content}}{{suffcontent}}{{$table}} {{/sections}} 文档内容按节点循环输出,pic0-pic3对应一个节点最多4张图片 代码:

java
//开始处理文档内容
        String outputUrl =fileName+".docx";
        //自定义模板策略
        ConfigureBuilder builder = Configure.newBuilder();
        builder.bind("table", new PaintTableRenderPolicy());
        builder.addPlugin('$', new PaintTableRenderPolicy());// poi-tl 自定义插件,表格绘制都在此类中处理
        XWPFTemplate compile = XWPFTemplate.compile(inputUrl,builder.build());
        //绑定输出内容
        Map<string object> model = new HashMap<>();
        List<map object>> list1 = new ArrayList<>();
        if (optList.size() > 0) {
            for (SysAgreeOpt opt : optList) {
                //遍历 判断是否表格
                Map<string object> datas = new HashMap<>();
                String sySubId = String.valueOf(opt.getSysSubId());
                String optional = opt.getOptional();//0:是 1:否 注意null
                String isShow =opt.getIsShow();//是否展示 0:是 1:否 注意null
                Boolean showNode = checkIfShow(optional,isShow);
                if(showNode){
//                  Integer sysTempId = opt.getSysTempId();
                    //加前缀 先判断正文或者下属表格是否有内容
                    String subContent = opt.getPreviewContent() == null ? "" : opt.getPreviewContent();//子模块预览
                    String preContent = opt.getPreContent() == null ? "" : opt.getPreContent().trim();//前缀
                    String suffContent = opt.getSuffContent() == null ? "" : opt.getSuffContent();//后缀

//                  List<sysagreeopt> childs = agreeOptService.getSubByTidAndPid(agreeId, sySubId);
                    String optType = opt.getDataType() == null ? "" :opt.getDataType();
                    if(!subContent.equals("") ||  (optType.equals("表格"))){
                        setPreContent(optType.equals("表格")?"":preContent,datas);
                    }
                    //正文 表格部分 遍历子节点表格内容
                    if((optType.equals("表格"))){
                        //查找节点表格数据
                        String tempCode = opt.getTempCode();
                        List<map object>> dataTables = new ArrayList<>();
                        Map<string object> table = getTableContent(agreeId,sySubId,tempCode);
                        dataTables.add(table);
                        datas.put("table", dataTables);

                    }else{// 非表格
                        //纯文本输出区域
                        String flag = opt.getNoFlag();//节点编号标志
                        String optName = opt.getOptName();//节点名称
                        String isShowTitle = opt.getIsShowTitle();//是否拼接标题
                        //正则表达式段落换行
                        //转换html内容为文档内容
                        String html = "" + subContent + "";
                        TextRenderData textData = getStyleData(html,11,optName);
                        datas.put("content", textData);
                        //节点名称不为空 并且要求展示节点名称的,才输出
                        if(checkIfShowTitle(isShowTitle,optName,flag)){
                            TextRenderData titleData = getTitleStyleData(optName,11);
                            datas.put("title", titleData);
                        }else {
                            datas.put("title", "");
                        }
                        //图片输出 注意多图 模板每个标签预留4个图片的位置
//                      String picUrl = "C:/ruoyi/uploadPath/upload/20200909/1599632248087043020.png";
                        setPics(subContent,datas);
                    }
                    //加后缀 和前缀一样判断
                    if(!subContent.equals("") || (optType.equals("表格"))){
                        setSuffContent(suffContent,datas);
                    }
                    list1.add(datas);
                }



            }
        }

        model.put("AA001",stdType);
        model.put("AA007",customerNameAbb);
        model.put("AA010",proUse);
        model.put("AA008",metalgrade);
        model.put("AA005",proShape);
        model.put("AA011",buyerCode);
        model.put("AA012",agreeCode);
        model.put("sections", list1);
        compile.render(model);
        //doc数据放完后 遍历正文内容(表格第三行)cell中表格样式统一处理
        XWPFDocument document = compile.getXWPFDocument();
        XWPFTableCell cell = document.getTableArray(0).getRow(2).getCell(0);
        List<xwpftable> tables = cell.getTables();
        for (XWPFTable table:tables){
            tableBorderStyle(table);
        }
        writeFile(compile,outputUrl);
</xwpftable></string></map></sysagreeopt></string></map></string>

问题:compile.render(model)运行后 model内可以看到6张图片都在,未报错。XWPFDocument document = compile.getXWPFDocument();document断点查看内容,只有两张图片,最终输出两张。

该提问来源于开源项目:Sayi/poi-tl

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

8条回答

  • weixin_39878989 weixin_39878989 4月前

    文档内容包括图片是由ueditor富文本编辑器处理,获取内容后获得img标签处理地址。

    java
    public void setPics(String picUrl,Map<string object> datas) throws IOException {
            Pattern p = Pattern.compile("<img>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>");
            Matcher m = p.matcher(picUrl);
            int count = 0;
            List<string> urlList = new ArrayList<>();
            while(m.find()){//匹配img标签中的图片地址
                count++;
                String url = m.group(1).replaceAll("/profile","");
                String url1 = url.replaceAll("http://localhost","");
                urlList.add(url1);
            }
            String preUrl = "C:/ruoyi/uploadPath";
            String preUrl1 = "http://localhost/profile";
            if(count>0){
                System.out.println(count);
                for(int i=0;i<count if string url="preUrl" urllist.get logger.debug fileinputstream picturerenderdata pic="new" fileinputstream.close pic.getpath pic.getdata pic.getheight pic.getwidth datas.put></count></string></string>
    点赞 评论 复制链接分享
  • weixin_39566578 weixin_39566578 4月前

    能直接给个可运行能复现问题的最小demo吗?

    点赞 评论 复制链接分享
  • weixin_39878989 weixin_39878989 4月前

    嗯,稍后准备一下。目前定位发现问题是:我自定义了一个table插件,按照文档写的,poi画表格。只要 ConfigureBuilder builder = Configure.newBuilder(); builder.bind("table", new PaintTableRenderPolicy()); 绑定自定义插件,就有这个问题。表格输出正常,一起用就凉了。 老哥靠你了,我这项目接近尾声,现在就卡这上面了

    点赞 评论 复制链接分享
  • weixin_39878989 weixin_39878989 4月前

    demo已提交,只要bind自定义插件,有没有数据,图片都会有异常,目前没发现规律。 我业务数据按照节点遍历,第一个节点1张图,第二个节点2张图,第三个节点3张图。这种情况就可能只有中间2张图,又有可能都没。demo是固定了5张图。 PoiDemo.zip

    点赞 评论 复制链接分享
  • weixin_39878989 weixin_39878989 4月前

    目前使用自定义插件用poi插入图片,也存在丢失情况。不知道是否需要代码里设置图片环绕方式等其他设置

    点赞 评论 复制链接分享
  • weixin_39566578 weixin_39566578 4月前

    自定义插件的代码看一下?

    点赞 评论 复制链接分享
  • weixin_39566578 weixin_39566578 4月前

    插件里面这一行

    java
    clearPlaceholder(context, true);
    

    ` 参数true改成false。

    点赞 评论 复制链接分享
  • weixin_39878989 weixin_39878989 4月前

    嗯,已解决。老哥稳

    点赞 评论 复制链接分享