java将前端传给后端的文字写入到word中

用户个人记录使用

前端代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- vue在线引入 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <!-- 在线引入echarts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.1/echarts.min.js"></script>
    <!-- axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>
    <div id="app">
        <el-row>
            姓名:{{userinfo.name}} <br>
            性别:{{userinfo.sex}} <br>
            年龄:{{userinfo.age}} <br>
            描述:{{userinfo.describe}} <br>
            <hr>
            <div v-for="(item,index) in userinfoList" :key="index">
                <span>姓名:{{item.name}}<br></span>
                <span>性别:{{item.sex}}<br></span>
                <span>年龄:{{item.age}}<br></span>
                <span>描述:{{item.describe}}<br></span>
                <hr>
            </div>
        </el-row>
        <el-row>
            <el-button type="primary" @click="exportword">将文字写入到word中</el-button>
        </el-row>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                userinfo: {
                    name: '罗辑',
                    sex: '男',
                    age: 23,
                    describe: '即使在宇宙尺度上是近在咫尺的四光年,对脆弱的生命来说也是不可想象的遥远,在这太空的江之头和江之尾,任何联系都细若游丝。'
                },
                userinfoList: [
                    {
                        name: '雷迪亚兹',
                        sex: '男',
                        age: 23,
                        describe: '面壁者,恒星级氢弹'
                    },
                    {
                        name: '希恩斯',
                        sex: '男',
                        age: 23,
                        describe: '面壁者,脑科学'
                    },
                    {
                        name: '泰勒',
                        sex: '男',
                        age: 23,
                        describe: '面壁者,量子幽灵部队'
                    },
                ]
            },
            methods: {

                async exportword() {
                    // 将数据放到请求体中
                    const requestbody = {
                        name: this.userinfo.name,
                        sex: this.userinfo.sex,
                        age: this.userinfo.age,
                        describe: this.userinfo.describe,
                        userinfoList: this.userinfoList
                    }
                    // 这里的axios我没有配置响应拦截器,如果配置了全局的响应拦截器的话要注意了,最好不要返回解构axios的data的结果,
                    // 这里是因为axios的data数据就是返回的,blob数据类型的数据,而不是我们平时返回JSON数据的格式,
                    // 如{code:20, message: '成功', data: object}这类的数据。 我们取数据一般都是res.data.data。但是这里如果后端
                    // 返回的是blob类型的数据,因为是以HttpServletResponse 流的形式返回的,这里会在res.data这里就是数据
                    // 至于这两个啥情况,具体自己console.log()打印一下结果判断一下就可以了,这里不唯一,根据情况console.log()打印一下结果
                    const res = await axios.post('http://localhost:8080/export/word', requestbody, { responseType: "blob" })
                    const link = document.createElement("a");
                    let blob = new Blob([res.data], { type: "application/msword" });
                    link.style.display = "none";
                    link.href = URL.createObjectURL(blob);
                    link.setAttribute("download", '三体资料(从前端传给后端的文字写到word中)详情.docx');
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    this.$message.success("导出成功")
                }
            },
            mounted() {
                // 注意调用顺序,先初始化echarts才给echarts赋值
                this.initEcharts()
                this.setEchartsOption()
            }
        })
    </script>
</body>

</html>

前端界面

点击导出后的结果,看后面的截图

java实现在doc文件指定位置添加印章 java写入word_ios

后端代码java

springboot项目

word模板,配置如下。最后导出word文档的样式就是word模板配置的样式,word模板是不是A4纸还是其他,这个跟自己word模板的设置有关,跟代码无关

java实现在doc文件指定位置添加印章 java写入word_前端_02

easypoi的maven坐标

<dependency>
       <groupId>cn.afterturn</groupId>
       <artifactId>easypoi-spring-boot-starter</artifactId>
       <version>4.4.0</version>
  </dependency>
@RestController
@RequestMapping("/export")
@CrossOrigin //前后端分离跨域,所以配置这个
public class ExportWordController {

    /**
     *
     * @param response
     * @param maps 这里使用map接收数据是因为这样更加方便,如果使用实体类接收,还要转化为Map<String,Object>这种类型,具体看另外一篇文章
     * @throws Exception
     */
    @PostMapping("/word")
    public void exportword(HttpServletResponse response, @RequestBody Map<String,Object> maps) throws Exception {
        // 读取模板文件所在的位置
        File filepath = new File("D:\\private\\javastudaykeshanchu\\javaweb\\echarts-demo\\src\\main\\resources\\templates\\wordtemplate.docx");
        String name = "从前端传给后端的文字写到word中";
        // filepath.getPath()是为了让路径变成string,否则下面的报错
        XWPFDocument word = WordExportUtil.exportWord07(filepath.getPath(), maps);
        String fileName = "三体资料(" + name + ")详情.docx";
        response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO8859-1"));
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        ServletOutputStream outputStream = response.getOutputStream();
        word.write(outputStream);
        outputStream.close();
        word.close();
    }

}

java后端:debugger跟word模板中对应的字段关系如下

java实现在doc文件指定位置添加印章 java写入word_java_03

最终结果为

java实现在doc文件指定位置添加印章 java写入word_ios_04

将下载之后的word文档打开结果如下所示

java实现在doc文件指定位置添加印章 java写入word_数据_05

注意事项

java实现在doc文件指定位置添加印章 java写入word_ios_06


java实现在doc文件指定位置添加印章 java写入word_前端_07


java实现在doc文件指定位置添加印章 java写入word_前端_08

java实现在doc文件指定位置添加印章 java写入word_数据_09


至于这么让格式统一,还望各位大佬指点一二