java导出word套打

这篇具有很好参考价值的文章主要介绍了java导出word套打。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 这篇文档手把手教你完成导出word套打,有这个demo,其他word套打导出都通用。

 1、主要依赖

        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.0</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.3.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

        <dependency>
            <groupId>repository.org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>
        <dependency>
            <groupId>repository.org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>

 2、模板excel见附件。

java导出word套打,java,开发语言

3、以下为导出代码逻辑:

package com.example.demo.excel;

import cn.hutool.poi.word.PicType;
import lombok.Data;

/**
 * 图片对象
 * @author xiajun
 */
@Data
public class WordImage {
    /**
     * 图片宽度
     */
    private int width = 100;

    /**
     * 图片高度
     */
    private int height = 100;

    /**
     * 图片地址
     * resource资源相对路径
     */
    private String path;

    /**
     * 字节流
     */
    private byte[] source;

    /**
     * 图片类型
     * 默认PNG
     *
     */
    private PicType imageType = PicType.PNG;


}

package com.example.demo.excel;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.word.Word07Writer;
import cn.hutool.poi.word.WordUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * word导出
 * @author xiajun
 */
@Slf4j
@RestController
@RequestMapping("mvc/word")
public class WordExport {
    @GetMapping(path = "/export")
    public void export(HttpServletResponse response) throws IOException {

        //1、============================模拟数据===============================
        Map<String, Object> params = new HashMap<>();
        params.put("${name}", "张三");
        params.put("${sex}", "男");
        params.put("${birth}", "1999.11");
        params.put("${age}", "25");
        params.put("${nation}", "汉族");
        params.put("${npn}", "四川成都");
        params.put("${bpn}", "四川成都");
        params.put("${pt}", "2017.02");
        params.put("${workTime}", "2016.03");
        params.put("${hn}", "健康");
        params.put("${beFawts}", "打篮球");
        params.put("${proTec}", "高级工程师");
        params.put("${degree}", "大学本科");
        params.put("${education}", "文学学士");
        params.put("${school}", "北京大学文院");
        params.put("${major}", "语言学");
        params.put("${dutyDegree}", "研究生毕业");
        params.put("${dutyEducation}", "其他");
        params.put("${dutySchool}", "四川大学土木学院");
        params.put("${dutyMajor}", "工程造价");
        params.put("${jobName}", "党委书记,组织部长,宣传部部长");

        //图片设置
        WordImage wordImage = new WordImage();
        wordImage.setHeight(150);
        wordImage.setWidth(100);
        byte[] imageBytes = FileUtil.readBytes("templates/fm.png");
        wordImage.setSource(imageBytes);
        params.put("@{photo}", wordImage);

        //一段长文本拆分,按照分行进行展示,例如简历这种
        String resume = "2017.08--2018.08  北京大学光华管理学院工商管理就读研究生\r2023.05--2023.09  简历测试职务\r2023.05--2023.09  外部人员挂职职务\r2023.09--         图书档案资料人员";
        params.put("${resume}", resume);

        //2、============================获取word模板===============================
        Word07Writer writer = WordUtil.getWriter(FileUtil.file("templates/mb.docx"));
        XWPFDocument document = writer.getDoc();//获取模板文档

        //3、============================获取模板文本的段落===============================
        Iterator<XWPFParagraph> paragraphStrings = document.getParagraphsIterator();
        while (paragraphStrings.hasNext()) {
            XWPFParagraph paragraph = paragraphStrings.next();
            log.info("文本段落文字:{}", paragraph.getText());
        }

        //4、============================获取模板表格的段落===============================
        Iterator<XWPFTable> tableIterator = document.getTablesIterator();
        while (tableIterator.hasNext()) {
            XWPFTable table = tableIterator.next();
            Iterator<XWPFTableRow> rows = table.getRows().listIterator();
            while (rows.hasNext()) {
                XWPFTableRow row = rows.next();
                Iterator<XWPFTableCell> cells = row.getTableCells().listIterator();
                while (cells.hasNext()) {
                    XWPFTableCell cell = cells.next();
                    List<XWPFParagraph> paragraphCells = cell.getParagraphs();
                    //只去表格中的一个段落
                    XWPFParagraph paragraph = CollectionUtil.isNotEmpty(paragraphCells) ? paragraphCells.get(0) : null;
                    if(paragraph != null){
                        String paragraphString = paragraph.getText();//段落中的文字
                        //占位符替换
                        TemplateProcessor.matchTemplate(paragraphString, params, paragraph);
                    }
                }
            }
        }

        //5、======================输出文件====================================
        // 设置content—type
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset:utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=data.docx");

        // 设置标题
        //Content-disposition是MIME协议的扩展,MIME协议指示MIME用户代理如何显示附加的文件。
        ServletOutputStream outputStream = response.getOutputStream();

        //将Writer刷新到OutPut
        writer.flush(outputStream, true);
        outputStream.close();
    }
}
package com.example.demo.excel;

import cn.hutool.poi.word.PicType;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

/**
 * word模板处理
 * @author xiajun
 */
@Slf4j
public class TemplateProcessor {


    final static Pattern patternString = Pattern.compile("\\$\\{[^{}]+}");//匹配文字
    final static Pattern patternTable = Pattern.compile("#\\{[^{}]+}");//匹配表格
    final static Pattern patternImg = Pattern.compile("@\\{[^{}]+}");//匹配照片

    /**
     * 模板占位符匹配
     *
     * @param template
     * @param variables
     * @return
     */
    public static void matchTemplate(String template, Map<String, Object> variables, XWPFParagraph paragraph) {
        //文字占位符替换
        Matcher matcher = patternString.matcher(template);
        while (matcher.find()) {
            String variable = matcher.group();//占位符
            dealXWPFRun(paragraph,variables,variable);//文档中占位符去除并设置套打文字
        }

        //图片占位符替换
        Matcher matcherImg = patternImg.matcher(template);
        while (matcherImg.find()) {
            String variable = matcherImg.group();//占位符
            dealXWPFRun(paragraph,variables,variable);//文档中占位符去除并设置套打图片

        }
    }

    /**
     * 获取文档占位符run,并且进行替换
     * @param paragraph
     * @param variables
     * @param variable
     */
    public static void dealXWPFRun(XWPFParagraph paragraph, Map<String, Object> variables, String variable){
        Object object = variables.get(variable);//需要替换的对象

        if (paragraph != null) {
            //获取占位符第一个
            String beginTag = variable.substring(0, 1);
            Iterator<XWPFRun> runs = paragraph.getRuns().listIterator();
            boolean flag = false;//是否开始拼接

            StringBuffer placeholder = new StringBuffer();
            List<List<XWPFRun>> allRuns = new ArrayList<>();//所有占位符涉及到的run
            List<XWPFRun> currentRuns = new ArrayList<>();//当前占位符涉及到的run
            while (runs.hasNext()) {
                XWPFRun run = runs.next();
                //开始符号处理
                if (run.text().contains(beginTag)) {
                    flag = true;
                }
                if (flag) {
                    String runString = run.text();
                    placeholder.append(runString);
                    currentRuns.add(run);
                }
                if (variable.equals(placeholder.toString())) {
                    allRuns.add(currentRuns);
                    currentRuns = new ArrayList<>();//重置list
                    flag = false;
                }
            }

            //将占位符涉及到的每个run list的第一个元素进行赋值,其他设置为空
            Iterator<List<XWPFRun>> iterator = allRuns.listIterator();
            while (iterator.hasNext()) {
                List<XWPFRun> runList = iterator.next();
                for (int i = 0; i < runList.size(); i++) {
                    if (i == 0) {
                        //文字处理
                        if(object instanceof String){
                            setRunText(runList.get(i),(String)object);
                        }
                        //图片处理
                        if(object instanceof WordImage){
                            setRunImg(runList.get(i),(WordImage)object);
                        }
                    } else {
                        runList.get(i).setText("", 0);
                    }
                }
            }
        }
    }

    /**
     * 设置Run中的图片
     * @param run
     * @param wordImage
     */
    private static void setRunImg(XWPFRun run, WordImage wordImage){
        PicType picType = wordImage.getImageType();
        try {
            run.setText("", 0);
            //往文档加入图片
            String picId = run.getDocument().addPictureData(wordImage.getSource(), picType.getValue());
            //将图片放在指定run中
            insertImageInRun(run, picId, run.getDocument().getNextPicNameNumber(picType.getValue()),
                    wordImage.getWidth(), wordImage.getHeight());
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置Run中的文本
     *
     * @param run
     * @param text
     */
    private static void setRunText(XWPFRun run, String text) {
        if (text.contains("\r")) {
            String[] split = text.split("\r");
            List<String> contents = Arrays.asList(split);

            run.setText(contents.get(0), 0);
            XWPFParagraph paragraph =(XWPFParagraph)run.getParent();

            XWPFTableCell cell = (XWPFTableCell)paragraph.getBody();

            for (int i = 1; i < contents.size(); i++) {

                //替换的肯定有段落获取第一个段落
                XWPFParagraph newParagraph = cell.addParagraph();
                newParagraph.getCTP().setPPr(paragraph.getCTP().getPPr());
                XWPFRun newRun = newParagraph.createRun();

                newRun.getCTR().setRPr(run.getCTR().getRPr());
                String content = contents.get(i);
                newRun.setText(content);
            }
        } else {
            run.setText(text,0);
        }
    }

    /**
     * run中插入图片
     *
     * @param run
     * @param picId
     * @param id
     * @param width
     * @param height
     */
    private static void insertImageInRun(XWPFRun run, String picId, int id, int width, int height) {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        CTInline inline = run.getCTR().addNewDrawing().addNewInline();

        String picXml = "" +
                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "         <pic:nvPicPr>" +
                "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                "            <pic:cNvPicPr/>" +
                "         </pic:nvPicPr>" +
                "         <pic:blipFill>" +
                "            <a:blip r:embed=\"" + picId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "            <a:stretch>" +
                "               <a:fillRect/>" +
                "            </a:stretch>" +
                "         </pic:blipFill>" +
                "         <pic:spPr>" +
                "            <a:xfrm>" +
                "               <a:off x=\"0\" y=\"0\"/>" +
                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "            </a:xfrm>" +
                "            <a:prstGeom prst=\"rect\">" +
                "               <a:avLst/>" +
                "            </a:prstGeom>" +
                "         </pic:spPr>" +
                "      </pic:pic>" +
                "   </a:graphicData>" +
                "</a:graphic>";

        XmlToken xmlToken = null;
        try {
            xmlToken = XmlToken.Factory.parse(picXml);
        } catch (XmlException xe) {
//            xe.printStackTrace();
            throw new RuntimeException("图片XML解析失败");
        }
        inline.set(xmlToken);
        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);

        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);

        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(id);
        docPr.setName("Picture " + id);
        docPr.setDescr("Generated");
    }
}

4、导出效果:

java导出word套打,java,开发语言

注意事项:如果你调整了代码设置数据,但是没生效,把target目录下的class文件删除重启哈就生效了。

============================好用记得点个赞哟!!!==========================文章来源地址https://www.toymoban.com/news/detail-803108.html

到了这里,关于java导出word套打的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java文件:XWPFDocument导出Word文档

    在Java项目开发过程中经常会遇到导出Word文档的业务场景。XWPFDocument是apache基金会提供的用户导出Word文档的工具类。 XWPFDocument:代表一个docx文档 XWPFParagraph:代表文档、表格、标题等各种的段落,由多个XWPFRun组成 XWPFRun:代表具有同样风格的一段文本 XWPFTable:代表一个表格

    2024年01月18日
    浏览(39)
  • Java 实现导出 Word 文档的方法详解

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 在 Java 应用程序中,有时候我们需要将数据导出为 Word 文档,以便进行文档的编辑、打印或共享。本文将介绍如何

    2024年02月15日
    浏览(41)
  • java按照模板导出pdf或者word

    (一)制作模板  1、在word里制作模板         因为PDF常用的软件不支持编辑,所以先用Word工具,如WPS或者Office新建一个空白Word文档,里面制作出自己想要的样式。 2、 将Word转换成PDF形式          将设置好的Word文档转换成PDF形式,保存起来。 3、编辑PDF准备表单 

    2024年02月06日
    浏览(52)
  • java实现将数据导出为word功能(文字,表格,图片的循环导出)

    这里需要注意的点!!!!!!!!!!!!!!!!! easypoi的版本必须在4.3.0以上,否则在导出图片的时候,只会导出图片的内存地址,却不能显示出图片。  解释一下模板中所填充的东西: 1.像这种:用两个花括号括起来的变量名,到时候会将变量名所指代的数据填充进

    2024年02月02日
    浏览(50)
  • JAVA POI富文本导出WORD添加水印

            在java 开发中 特别是OA开发中,经常会遇到导出word的操作,同时随时AI时代的到来,很多导出文档都需要增加水印标识,用来追溯数据生产方。         本文将介绍如何通过操作POI 来实现导出富文本到word ,并在文档中追加水印功能。 导入POM         首先我们

    2024年02月03日
    浏览(56)
  • java使用apache.poi导出word文件

    功能说明: 将试卷导出word,并可以打印,装订,效果图: 下面是实现代码:

    2024年02月15日
    浏览(49)
  • Java POI导出富文本的内容到word文档

    当创建使用富文本编辑器,操作完的数据,传输到后台都是带有html标签的。 如:h1标题头/h1h2第二个标题/h2a href=\\\"www.baidu.com\\\"百度搜索/a 我们想把富文本数据转换为Word内容。 Word是完全支持html标签的,但是我们获取到的富文本内容并不是完整的html代码,所有我们需要先补全

    2024年02月09日
    浏览(50)
  • 【Java Easypoi & Apache poi】 Word导入与导出

            如果这里造成了读取resources下的文件返回前端乱码问题:除了HttpServletResponse响应中设置字体问题,还有可能是因为在编译期文件就已经乱码了,所以需要在pom.xml中增加以下配置。

    2024年02月10日
    浏览(56)
  • 轻松学会Java导出word,一篇文章就够了!

    很多小伙伴在工作中,可能又这样一个需求:根据word模板去填充数据,变成我们想要的word文档,这是很多刚进入职场的小白都会碰到的需求。 当遇上这种需求,我们可以通过这篇文章要讲的 poi-tl 来做处理。 我们先在指定的位置创建一个测试文档。我这边直接在springboot中的

    2024年02月07日
    浏览(43)
  • Java的XWPFTemplate工具类导出word.docx的使用

    代码 模板使用{{占位符}} 图片{{@占位符}} 换行n 读取文字:{{?photoCollection}}{{pho}}{{/photoCollection}} 读取照片:{{?photoCollection}} {@{pho}} {{/photoCollection}} 特别注意:读取照片的时候需要有一个空格才会显示,找了好久的问题,最后加一个空格解决了

    2024年01月20日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包