Java使用XDocReport导出Word(带图片)

简介

这次的内容是关于Java实现导出Word的文章,主要应用技术为XDocReport。
以下内容主要为使用方法,详情可以去官网了解更多---->XDocRepor

XDocReport表示XML文档报告。这是一个Java API,可以将MS Office (docx, pptx)或OpenOffice (odt), LibreOffice (odt)创建的XML文档与Java模型合并,生成报告,并在需要时将其转换为另一种格式(PDF, XHTML…)。使用xdoreport:
你用MS Word (docx, pptx)或OpenOffice (odt, ods)创建文档
您使用Velocity或Freemarker语法来设置要替换的变量。例如,您可以在文档中输入(这里使用Velocity语法):Hello $name !
通过合并文档与来自Java模型的’world’值来替换变量,以生成包含内容的报告:
Hello world!

示例

Word模板
在这里插入图片描述
导出样例
在这里插入图片描述

实现方式

实现方式的过程需要制作Word模板,本次模拟前台调用效果,后端提供Api供调用,文件从浏览器下载。

Maven依赖

  		<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.jxls</groupId>
            <artifactId>jxls</artifactId>
            <version>2.6.0</version>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.jxls</groupId>
            <artifactId>jxls-poi</artifactId>
            <version>1.2.0</version>
        </dependency>

        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.core</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.document</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.template</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
            <version>2.0.2</version>
        </dependency>

Word模板制作

Word模板文字(四步)
  1. 本次示例使用WPS
  2. 在需要加入导出文字的部分,Windows摁下Ctrl+F9,Mac摁下command+F9,生成域。

在这里插入图片描述
3. 在生成的域上右键点击【编辑域】

在这里插入图片描述
4. 选择【邮件合并】,在域代码处的【MERGEFIELD】后边输入【 “${test}”】(实际变量由代码IContext对象的值决定,下边代码会有体现。)
在这里插入图片描述

Word模板图片(五步)

1.本次示例使用WPS。
2.在需要图片的地方先插入一张图片
在这里插入图片描述
3.导入图片后,可以自行调整大小,这样可以让导出的图片按照模板的大小生成。
4.选中图片,选择插入,点击书签。
在这里插入图片描述

5.输入书签名,点击添加。书签名作用与模板文字的域相同。
在这里插入图片描述

具体实现

  1. 现将模板放到项目工程的以下位置,resources下创建static
    在这里插入图片描述

  2. 导入以下代码,以下代码为全部实现过程,包含url转为File流,读取模板文件。文字生成,图片生成,注(如果需要文件保存到本次,请根据代码注释部分,启用部分代码)

package xxx.utils;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.FileImageProvider;
import fr.opensagres.xdocreport.document.images.IImageProvider;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

@Slf4j
public class WordUtils {
    //文字生成实现类实现类
    public static void textGeneration(HttpServletResponse response) throws Exception {
        //1.通过freemarker模板引擎加载文档,并缓存到registry中
        InputStream in = null;
        OutputStream out = null;
        try {
            String path = Thread.currentThread().getContextClassLoader().getResource("static/elTest.docx").getPath();
            in = new FileInputStream(path);
            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
            //2.设置填充字段、填充类以及是否为list。
            FieldsMetadata fieldsMetadata = report.createFieldsMetadata();
            IContext context = report.createContext();
            context.put("name", "张三");
            context.put("gender", "男");
            context.put("type", "专家人才");
            context.put("address", "东");
            context.put("age", "40");
            context.put("troops", "XX部");
            fieldsMetadata.addFieldAsImage("pic");
            //获得图片文件
            File file = UrltoFile("https://img1.baidu.com/it/u=1960110688,1786190632&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281");
            IImageProvider iImageProvider = new FileImageProvider(file, false);
            context.put("pic", iImageProvider);
            String outFileName = new Date().toString() ;
            //如果需要文件保存在本地,则放开以下注释。注释response的代码。
//            out = Files.newOutputStream(new File("输出路径").toPath());
            report.setFieldsMetadata(fieldsMetadata);
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + outFileName + ".docx");
            out = response.getOutputStream();
            report.process(context, out);
        } catch (IOException e) {
            log.error("读取Word模板异常", e);
        } catch (XDocReportException e) {
            log.error("word模板生成失败", e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //将Url转换为File
    public static File UrltoFile(String url) throws Exception {
        HttpURLConnection httpUrl = (HttpURLConnection) new URL(url).openConnection();
        httpUrl.connect();
        InputStream ins = httpUrl.getInputStream();
        File file = new File(System.getProperty("java.io.tmpdir") + File.separator + "xie");//System.getProperty("java.io.tmpdir")缓存
        if (file.exists()) {
            file.delete();//如果缓存中存在该文件就删除
        }
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        int len = 8192;
        byte[] buffer = new byte[len];
        while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;

    }

    //将File对象转换为byte[]的形式
    public static byte[] FileTobyte(File file) {
        FileInputStream fileInputStream = null;
        byte[] imgData = null;

        try {

            imgData = new byte[(int) file.length()];

            //read file into bytes[]
            fileInputStream = new FileInputStream(file);
            fileInputStream.read(imgData);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return imgData;
    }
}

3.Api入口示例。

package xxx.utils;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("test")
public class TestController {

    @Operation(summary = "Word导出生成文字图片")
    @GetMapping()
    public void test(HttpServletResponse response) throws Exception {
        WordUtils.textGeneration(response);
    }
}

4.请求API,生成文档。

注意事项

1.结合自身实际需要,自行编辑Word模板,及代码中的IContext对象的值。
2.以下代码False表示图片大小由模板图片大小决定,如需自己定义大小,可以修改为true。

 IImageProvider iImageProvider = new FileImageProvider(file, false);

3.如果需要从0搭建demo,可参考另一篇创建SpringBoot工程使用Maven及Spring Initializer快速创建Spring Boot项目

结论

以上操作步骤为实际操作得出的demo,试验可应对复杂场景,如合同导出、发票生成,根据数据库数据导出对应数据。

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
导出图片Word表格涉及到前端与后端的协作。下面是一个简单的实现步骤: 1. 前端使用JavaScript创建一个包含表格和图片的HTML页面。表格可以使用HTML的table标签来构建,而图片则可以使用img标签来引用。为了将图片嵌入到表格中,可以将图片转换为Base64编码。 2. 在前端页面中使用JavaScript的Canvas API将图片渲染到Canvas元素上。首先,将图片加载到一个img元素中,然后将img元素绘制到Canvas上。最后,使用Canvas的toDataURL方法将Canvas内容转换为Base64编码的图片数据。 3. 前端可以使用第三方库,如jsPDF或html-docx-js,将HTML内容导出Word文档。这些库提供了将HTML转换为Word文档的功能,支持表格和图片导出。在导出Word文档时,可以将Base64编码的图片数据添加到Word文档中,以使图片嵌入到文档中。 4. 后端使用Java开发一个接口,接收前端发送的HTML内容和图片数据。后端可以使用Apache POI库操作Word文档,将接收到的HTML内容转换为Word表格,并将图片数据添加到Word文档中。通过将图片数据以二进制形式插入到Word文档的方式,图片可以在Word文档中正确显示。 5. 前端发送HTTP请求将HTML内容和图片数据发送到后端接口。可以使用AJAX或Fetch进行发送。 6. 后端接收到请求后,根据接收到的HTML内容和图片数据,使用Apache POI创建Word文档并将内容写入文档。 7. 后端将生成的Word文档返回给前端。 通过以上步骤,前端JS和后端Java可以实现导出图片Word表格。前端负责生成HTML内容和处理图片,并将数据发送到后端。而后端负责将HTML内容转换为Word文档,并将图片数据添加到文档中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值