使用docx4j将数据导出到word中的多个表格并导出图片

    public static <T> void getDocx(String fileName, List<Map<String, Object>> List) throws Exception {
        //模板路径
        String testPath = "docx/导出.docx";
        //输出路径1
        String outPath = "D:/1/"+fileName+".docx";
        //书签名称
        String bookmarkName = "bookmark";
        // 图片路径
        String imagePath = "C:\\Users\\Administrator\\Desktop\\1.jpg";
        
        WordprocessingMLPackage wordMlPackage = WordprocessingMLPackage.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(testPath));;
        org.docx4j.finders.ClassFinder find = new ClassFinder(Tbl.class);
        new TraversalUtil(wordMlPackage.getMainDocumentPart().getContent(),find);


        // 提取正文
        MainDocumentPart mainDocumentPart = wordMlPackage.getMainDocumentPart();
        Document wmlDoc = (Document) mainDocumentPart.getJaxbElement();
        Body body = wmlDoc.getBody();
        // 提取正文中所有段落
        List<Object> paragraphs = body.getContent();
        // 提取书签并创建书签的游标
        RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
        new TraversalUtil(paragraphs, rt);


        //构造循环列表的数据
        Map<String, String> mappings = null;

        List wordInformationDataList = null;
        for (Map<String,Object> data:List
        ) {
            String type = (String) data.get("type");
            
            //如果type为1,,则设置为全局变量
            if ("1".equals(type)) {
                List datalist = (List) data.get("datalist");
                  mappings = (HashMap<String, String>) datalist.get(0);
                  mappings = mapSetNullToBlankString(mappings);
            } else {
                wordInformationDataList = (List) data.get("datalist");
                //读取第几个表格
                Tbl table = (Tbl) find.results.get(Integer.valueOf(type)-1);
//        获取模板行的XML数据
                Tr dynamicTr = (Tr) table.getContent().get(1);
                String dynamicTrXml = XmlUtils.marshaltoString(dynamicTr);
                List<Map<String,Object>> dataList= new ArrayList<Map<String, Object>>() ;
                dataList = wordInformationDataList;
                for (Map<String,Object> dataMap :dataList){
                    Map map = mapSetNullToBlankString(dataMap);
                    Tr newTr = (Tr)XmlUtils.unmarshallFromTemplate(dynamicTrXml,map);
                    table.getContent().add(newTr);
                }
                //删除模板行的站位行
                table.getContent().remove(1);
            }


        }

        // 遍历书签
        for (CTBookmark bm:rt.getStarts()) {
            // 这儿可以对单个书签进行操作,也可以用一个map对所有的书签进行处理
            if (bm.getName().equals(bookmarkName)){
                // 读入图片并转化为字节数组,因为docx4j只能字节数组的方式插入图片
                InputStream is = new FileInputStream(imagePath);
                byte[] bytes = IOUtils.toByteArray(is);
                // 穿件一个行内图片
                BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMlPackage, bytes);

                // createImageInline函数的前四个参数我都没有找到具体啥意思,,,,
                // 最有一个是限制图片的宽度,缩放的依据
                Inline inline = imagePart.createImageInline(null, null, 0,1, false, 1800);
                // 获取该书签的父级段落
                P p = (P)(bm.getParent());
                ObjectFactory factory = new ObjectFactory();
                // R对象是匿名的复杂类型,然而我并不知道具体啥意思,估计这个要好好去看看ooxml才知道
                R run = factory.createR();
                // drawing理解为画布?
                Drawing drawing = factory.createDrawing();
                drawing.getAnchorOrInline().add(inline);
                run.getContent().add(drawing);
                p.getContent().add(run);
            }
        }


        //替换全局变量
        wordMlPackage.getMainDocumentPart().variableReplace(mappings);
        //输出文件
        Docx4J.save(wordMlPackage,new File(outPath));



    }
mapSetNullToBlankString(Map map) 是将map中的null替换为空字符串的方法,docx4j使用模板导出时,如果值为null会在表格内留下字段名。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值