JAVA POI富文本导出WORD添加水印

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

背景    

        在java 开发中 特别是OA开发中,经常会遇到导出word的操作,同时随时AI时代的到来,很多导出文档都需要增加水印标识,用来追溯数据生产方。

        本文将介绍如何通过操作POI 来实现导出富文本到word ,并在文档中追加水印功能。

代码实现

导入POM

        首先我们需要导入需要引用的POM文件

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

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

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.14.3</version>
        </dependency>

        commons-io包为poi依赖如果缺失,会提示NotFoundClass 。

         jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

将html转换为dom文档

        采用Jsoup处理类来实现将html内容转换为dom结构,便于后续操作

  public static Document convertToDom(String htmlContent) {
        Document doc = Jsoup.parse(htmlContent, "UTF-8");
        return doc;
    }

基于POI处理dom内容 

        首先解析dom中的body 获取body下的所有元素

        再根据Element 中解析的tagName来分别处理在word文档中不同样式,也可以Element.attr属性来获取html中的自定义属性,类似js或者xml node节点的操作

        针对图片由于html中的图片都来源于网络,所以本文基于实际操作,将图片转换为base64编码,保证图片在word中正确展示

 /**
     * 解析Document 并处理 body下的所有Elements
     *
     * @param htmlDocument
     * @param wordDocument
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static void parseDocument(Document htmlDocument, XWPFDocument wordDocument) throws IOException, InvalidFormatException {
        Elements elements = htmlDocument.body().children();
        for (Element element : elements) {
            parseElement(element, wordDocument);
        }
    }

    /**
     * 解析Elements 处理标签中指定tagName
     *
     * @param element
     * @param wordDocument
     * @throws IOException
     * @throws InvalidFormatException
     */
    private static void parseElement(Element element, XWPFDocument wordDocument) throws IOException, InvalidFormatException {
        // 处理元素类型,例如<p>、<h1>等
        String tagName = element.tagName();
        switch (tagName) {
            case "p":
                // 处理段落
                // 也可以根据 element.attr来处理不通css样式的文字
                String text = element.text();
                XWPFRun runP = wordDocument.createParagraph().createRun();
                runP.setText(text);
                break;
            case "h1":
            case "h2":
                // 处理标题1 可以自定义样式
                //此处可以处理不同标签
                String heading1Text = element.text();
                XWPFRun runH1 = wordDocument.createParagraph().createRun();
                runH1.setText(heading1Text);
                runH1.setBold(true);
                runH1.setFontSize(16);
                break;
            case "img":
                //处理图片,由于html的图片来源为网络图片,所以此处将网络图片转换为base64编码,并插入word文档
                XWPFRun run = wordDocument.createParagraph().createRun();
                String src = element.attr("src").toString();
                byte[] imageData = org.apache.commons.codec.binary.Base64.decodeBase64(ImageToBase64ByOnline(src));
                run.addPicture(new ByteArrayInputStream(imageData), XWPFDocument.PICTURE_TYPE_JPEG, "image", Units.toEMU(300), Units.toEMU(200));
                break;
            default:
                break;
        }
        // 递归处理子元素
        Elements children = element.children();
        for (Element child : children) {
            parseElement(child, wordDocument);
        }
    }

 基于POM添加水印

        调用POI 的 XWPFHeaderFooterPolicy.createWatermark api可以添加水印,但是添加之后会存在后续编辑新增段落水印不会新增,同时样式不能调整,位置为水平居中效果不是很好看,基于系统createWatermark水印效果,本方法提供了增强具体可以看代码

  /**
     * 添加水印,在调用系统api添加水印的同时,并针对系统水印的确定进行额外处理
     *
     * @param doc
     * @param markStr
     */
    public static void addWatermark(XWPFDocument doc, String markStr) {
        XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
        if (headerFooterPolicy == null) {
            //兼容处理
            headerFooterPolicy = doc.createHeaderFooterPolicy();
        }
        //调用API添加水印,效果不好为水平居中
        headerFooterPolicy.createWatermark(markStr);

        //处理后续文档更新水印逻辑
        XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);

        XWPFParagraph paragraph;
        paragraph = header.getParagraphArray(0);

        //设置水印样式和位置,保持倾斜角度更好看和实用
        paragraph.getCTP().newCursor();
        org.apache.xmlbeans.XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(
                new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
        if (xmlobjects.length > 0) {
            CTShape ctshape = (CTShape) xmlobjects[0];
            ctshape.setFillcolor("#C0C0C0");
            ctshape.setStyle(ctshape.getStyle() + ";rotation:315");
        }
    }

完整代码

package com.dayouz.word;

import com.microsoft.schemas.vml.CTShape;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author dayouz
 * @classname WordUtil
 * @desc JAVA POI 实现 富文本导出 WORD 和添加水印
 */
public class WordUtil {


    /**
     * 将html内容转换为Document结构
     *
     * @param htmlContent
     * @return
     */
    public static Document convertToDom(String htmlContent) {
        Document doc = Jsoup.parse(htmlContent, "UTF-8");
        return doc;
    }

    /**
     * 解析Document 并处理 body下的所有Elements
     *
     * @param htmlDocument
     * @param wordDocument
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static void parseDocument(Document htmlDocument, XWPFDocument wordDocument) throws IOException, InvalidFormatException {
        Elements elements = htmlDocument.body().children();
        for (Element element : elements) {
            parseElement(element, wordDocument);
        }
    }

    /**
     * 解析Elements 处理标签中指定tagName
     *
     * @param element
     * @param wordDocument
     * @throws IOException
     * @throws InvalidFormatException
     */
    private static void parseElement(Element element, XWPFDocument wordDocument) throws IOException, InvalidFormatException {
        // 处理元素类型,例如<p>、<h1>等
        String tagName = element.tagName();
        switch (tagName) {
            case "p":
                // 处理段落
                // 也可以根据 element.attr来处理不通css样式的文字
                String text = element.text();
                XWPFRun runP = wordDocument.createParagraph().createRun();
                runP.setText(text);
                break;
            case "h1":
            case "h2":
                // 处理标题1 可以自定义样式
                //此处可以处理不同标签
                String heading1Text = element.text();
                XWPFRun runH1 = wordDocument.createParagraph().createRun();
                runH1.setText(heading1Text);
                runH1.setBold(true);
                runH1.setFontSize(16);
                break;
            case "img":
                //处理图片,由于html的图片来源为网络图片,所以此处将网络图片转换为base64编码,并插入word文档
                XWPFRun run = wordDocument.createParagraph().createRun();
                String src = element.attr("src").toString();
                byte[] imageData = imageToBase64(src);
                run.addPicture(new ByteArrayInputStream(imageData), XWPFDocument.PICTURE_TYPE_JPEG, "image", Units.toEMU(300), Units.toEMU(200));
                break;
            default:
                break;
        }
        // 递归处理子元素
        Elements children = element.children();
        for (Element child : children) {
            parseElement(child, wordDocument);
        }
    }

    /**
     * 添加水印,在调用系统api添加水印的同时,并针对系统水印的确定进行额外处理
     *
     * @param doc
     * @param markStr
     */
    public static void addWatermark(XWPFDocument doc, String markStr) {
        XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
        if (headerFooterPolicy == null) {
            //兼容处理
            headerFooterPolicy = doc.createHeaderFooterPolicy();
        }
        //调用API添加水印,效果不好为水平居中
        headerFooterPolicy.createWatermark(markStr);

        //处理后续文档更新水印逻辑
        XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);

        XWPFParagraph paragraph;
        paragraph = header.getParagraphArray(0);

        //设置水印样式和位置,保持倾斜角度更好看和实用
        paragraph.getCTP().newCursor();
        org.apache.xmlbeans.XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(
                new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
        if (xmlobjects.length > 0) {
            CTShape ctshape = (CTShape) xmlobjects[0];
            ctshape.setFillcolor("#C0C0C0");
            ctshape.setStyle(ctshape.getStyle() + ";rotation:315");
        }
    }

    /**
     * 在线图片转换成base64字符串
     *
     * @param imgURL 图片地址
     * @return
     */
    private static byte[] imageToBase64(String imgURL) {
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        try {
            // 创建URL
            URL url = new URL(imgURL);
            byte[] by = new byte[1024];
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream is = conn.getInputStream();
            // 将内容读取内存中
            int len = -1;
            while ((len = is.read(by)) != -1) {
                data.write(by, 0, len);
            }
            // 关闭流
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data.toByteArray();

    }

    public static void main(String[] args) throws IOException, InvalidFormatException {
        //初始化文档
        XWPFDocument doc = new XWPFDocument(new FileInputStream("input.docx"));
        //将html转换为dom
        Document document = convertToDom("");
        //处理dom添加到word
        parseDocument(document, doc);
        //添加水印
        addWatermark(doc, "CSDN");
        //保存本地
        doc.write(new FileOutputStream("output.docx"));
        doc.close();
    }
}

        以上内容就是java 通过poi来实现富文本导出到word文档,针对图片也给力处理方式demo,特别是针对水印功能,针对系统函数的功能和美观上的缺失做了方法扩展,文章来源地址https://www.toymoban.com/news/detail-775515.html

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

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

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

相关文章

  • 【导出Word】如何使用Java+Freemarker模板引擎,根据XML模板文件生成Word文档(只含文本内容的模板)

    这篇文章,主要介绍如何使用Java+Freemarker模板引擎,根据XML模板文件生成Word文档。 目录 一、导出Word文档 1.1、基础知识 1.2、制作模板文件 1.3、代码实现 (1)引入依赖 (2)创建Freemarker工具类 (3)测试案例代码 (4)运行效果 Word文件有两种后缀格式,分别是:doc和docx,

    2024年02月13日
    浏览(45)
  • Java poi之word文本替换

    应公司需求,需实现以下功能 word文本内容的替换; word文本内容的提取; word文档中图片的提取存放 此文章将使用Apache POI实现Word文档中文本内容的替换更新; Apache POI 是基于 Office Open XML 标准(OOXML)和 Microsoft 的 OLE 2 复合文档格式(OLE2)处理各种文件格式的开源项目。 简

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

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

    2024年02月15日
    浏览(36)
  • Java 使用 poi 和 aspose 实现 word 模板数据写入并转换 pdf 增加水印

    本项目所有源码和依赖资源都在文章顶部链接,有需要可以下载使用 1. 需求描述 从指定位置读取一个 word 模板 获取业务数据并写入该 word 模板,生成新的 word 文档 将新生成的 word 文档转换为 pdf 格式 对 pdf 文档添加水印 2. 效果预览 word 模板 带水印的 pdf 文档 3. 实现思路

    2024年02月08日
    浏览(38)
  • java 导出word,java根据提供word模板导出word文档

    本文主要讲解,利用poi-tl在word中动态生成表格行,进行文字、图片填充。一共提供了两种方式,1.基于本地文件 2.基于网络文件 本文讲解思路,1.先看示例,2. 示例对应的代码展示 3. 基本概念讲解(api自行查阅文档)。 这样便于快速展示,不符合你的业务需求的可以直接划走

    2024年02月14日
    浏览(31)
  • Java poi之word文本图片内容提取

    应公司需求,需实现以下功能 word文本内容的替换; word文本内容的提取; word文档中图片的提取存放 此文章将使用Apache POI实现Word文档中文本内容及图片的提取; Apache POI 是基于 Office Open XML 标准(OOXML)和 Microsoft 的 OLE 2 复合文档格式(OLE2)处理各种文件格式的开源项目。

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

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

    2024年02月10日
    浏览(47)
  • 【Easypoi & Apache poi】 Java后端 Word导入与导出

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

    2024年02月11日
    浏览(41)
  • java 使用POI-TL根据word模版,生成word文件,含图片,富文本。

    1.引入mavna坐标` 2 .poi-tl-ext插件主要用于富文本内容格式在word展现 3.word模版创建 3.具体代码实现 4.本文的miniourl路径实质为网络路径的文件。

    2024年02月16日
    浏览(46)
  • Android 基于POI库,根据模板导出word文档

    由于项目需求,需要根据用户提供的word模板,填充动态内容生成新的word,为了记录自己的踩坑日记,记录一下。 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对文档读和写的功能。 这里给出官网链接-POI官网,同时下载版本也在官网链接中,可

    2024年01月18日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包