poi导出数据到word,带图片且图片数量不确定(能确定数量范围,这里是3-20张)

poi导出数据到word,带图片且图片数量不确定(能确定数量范围,这里是3-20张),第1张

poi导出数据到word,带图片且图片数量不确定(能确定数量范围,这里是3-20张)

1.导入依赖
maven版:


    org.apache.poi
    poi
    4.1.1


    org.apache.poi
    poi-ooxml
    4.1.1


    org.jxls
    jxls
    2.6.0
    
        
            ch.qos.logback
            logback-core
        
    


    org.jxls
    jxls-poi
    1.2.0


    fr.opensagres.xdocreport
    fr.opensagres.xdocreport.core
    2.0.2


    fr.opensagres.xdocreport
    fr.opensagres.xdocreport.document
    2.0.2


    fr.opensagres.xdocreport
    fr.opensagres.xdocreport.template
    2.0.2


    fr.opensagres.xdocreport
    fr.opensagres.xdocreport.document.docx
    2.0.2


    fr.opensagres.xdocreport
    fr.opensagres.xdocreport.template.freemarker
    2.0.2


    org.freemarker
    freemarker
    2.3.23


    commons-io
    commons-io
    2.5

gradle版:

    compile "fr.opensagres.xdocreport:fr.opensagres.xdocreport.core:2.0.2"
    compile "fr.opensagres.xdocreport:fr.opensagres.xdocreport.document:2.0.2"
    compile "fr.opensagres.xdocreport:fr.opensagres.xdocreport.document.docx:2.0.2"
    compile "fr.opensagres.xdocreport:fr.opensagres.xdocreport.template:2.0.2"
    compile "fr.opensagres.xdocreport:fr.opensagres.xdocreport.template.freemarker:2.0.2"
    compile "org.freemarker:freemarker:2.3.23"
    compile "commons-io:commons-io:2.5"
    compile "org.apache.poi:poi:3.14"
    compile "org.apache.poi:poi-ooxml:3.14"

2.创建导出模板

纯文字使用${}占位,图片使用建立初始化图片并添加书签的方式占位,
书签名就是datamap的键名,多张图片添加多个书签

3.编写代码(这里使用浏览器下载方式导出)
(1)导出工具方法

    public static void exportFile (
            HttpServletResponse response,
            Map fileDataMap,
            String fileName,
            Map map,
            List list) throws IOException, XDocReportException {
            // 获取Word模板,模板存放路径在项目的resources目录下
            // 这里的Kit为当前工具方法的类名,如果不是静态方法可以直接用this
          InputStreamins= Kit.class.getResourceAsStream(fileName);
            // 注册xdocreport实例并加载FreeMarker模板引擎
		  IXDocReportreport=XDocReportRegistry.getRegistry().loadReport(ins, TemplateEngineKind.Freemarker);
            // 创建xdocreport上下文对象
            IContext context = report.createContext();
            //添加文本数据
            if (map != null) {
                for (String s : map.keySet()) {
                    context.put(s, map.get(s));
                }
            }
            //添加循环表格数据(需要自行添加,模板对应加上关键字)
            if (list != null) {
                context.put("resultList", list);
                // 创建字段元数据
                Fieldsmetadata fm = report.createFieldsmetadata();
                // Word模板中的表格数据对应的集合类型
                fm.load("resultList", Object.class, true);
            }
            Fieldsmetadata metadata = report.createFieldsmetadata();
            // 替换word模板中的动态图片
            if (fileMap != null) {
                for (String s : fileMap.keySet()) {
                    IImageProvider zp = new FileImageProvider((fileMap.get(s)), true);
                    zp.setSize(130F, 130F);
                    metadata.addFieldAsImage(s);
                    report.setFieldsmetadata(metadata);
                    context.put(s, zp);
                }
            }
            // 浏览器端下载
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            response.setHeader(
                    "Content-Disposition",
                    "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
            report.process(context, response.getOutputStream());

    }
 

(2)业务逻辑代码

try{
		Map fileMap = null;
		Map exportMap = new hashMap();
		exportMap.put("???","data");
            int num = 1;
            //由于poitl和导入功能用的poi版本冲突,无法用,这里使用IXDocReport对象做导出
            //可以循环添加,键名可以拼接为img1,img2,img3。。。,模板书签名对应
            //需要导出的文件集合,对接实际业务service
            List list = new arrayList();
           	if(list != null) {
           	fileMap = new hashMap();
            for (File f : list) {
            	fileMap.put("img" + num , f);
            	num ++;
           }
        }
         Kit.exportFile(response, fileMap, "模板名称.docx", exportMap, null);
       } catch (Exception e) {
         e.printStackTrace();
       }

(3)因为我们业务文件接口返回的是byte数组,所以这里提供一个byte数组转File对象的方法(网上c的)

    
    public static File createTmpFile(
            InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException {
        File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile);
        resultFile.deleteOnExit();
        FileUtils.copyToFile(inputStream, resultFile);
        return resultFile;
    }

    
    public static File bytesToFile(byte[] bytes, String fileType) throws IOException {
        return createTmpFile(
                new ByteArrayInputStream(bytes),
                UUID.randomUUID().toString(),
                fileType,
                Files.createTempDirectory("tempFile").toFile());
    }

4.那么问题来了,图片数量不定怎么确定初始化图片再添加书签呢,困扰了很久,最后直接用20张纯白图片(这里采用微信截图,截了很小一张,100张也没有几k,全都添加对应书签,不够20张也看不出来,缺点是不满20张会空一行出来),弄好后调用方法点击导出ok

注:方法思路由该贴而来
https://blog.csdn.net/plxddyxnmd/article/details/109129838

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5609355.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)