java实现word中插入附件(支持所有文件格式)

前言

通过java在word文档中嵌入附件,需使用ole方式嵌入,包含图标生成,编写demo快速实现。

实现demo代码如下:

1. 引入依赖

xml 复制代码
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>5.2.2</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>5.2.2</version>
</dependency>

2. 组装附件图标(图标+附件名称)

java 复制代码
package com.example.demo.example;

import com.example.demo.AttachmentIconEnum;
import org.apache.commons.codec.binary.Base64;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class AttachmentIconUtils {

    /**
      * @Description //TODO 获取附件图标
      * @Date 2025/12/12 16:35
      * @Param [fileName]
      * @return byte[]
     **/
    public static byte[] getAttachmentIconByte(String fileName) {
        String suffix = "";
        if(fileName.indexOf(".") != -1){
            suffix = fileName.split("\\.")[1];
        }
        String base64Icon;
        switch(suffix){
            case "doc":
            case "docx":
                base64Icon = AttachmentIconEnum.DOCX.getIcon();
                break;
            case "xls":
            case "xlsx":
                base64Icon = AttachmentIconEnum.XLSX.getIcon();
                break;
            default:
                base64Icon = AttachmentIconEnum.DEFAULT.getIcon();
                break;
        }
        String encodingPrefix = "base64,";
        if(base64Icon.contains(encodingPrefix)) {
            int contentStartIndex = base64Icon.indexOf(encodingPrefix) + encodingPrefix.length();
            base64Icon = base64Icon.substring(contentStartIndex);
        }
        byte[] templateIconBytes = Base64.decodeBase64(base64Icon);
        try {
            return makeAttachmentIcon(templateIconBytes,fileName);
        }catch (Exception e){
            return templateIconBytes;
        }
    }

    /**
      * @Description //TODO 制作附件图标
      * @Date 2025/12/12 16:35
      * @Param [templateIconBytes, fileName]
      * @return byte[]
     **/
    public static byte[] makeAttachmentIcon(byte[] templateIconBytes,String fileName) throws Exception {
        // 读取要插入的图片
        try(InputStream inputStream = new ByteArrayInputStream(templateIconBytes);
            ByteArrayOutputStream baos = new ByteArrayOutputStream()){
            BufferedImage overlayImage = ImageIO.read(inputStream);
            // 计算新图片尺寸:宽度 = 插入图宽度,高度 = 插入图高度 + 文字区域(60px)
            int width = overlayImage.getWidth() + 60;
            int textHeight = 60;
            int height = overlayImage.getHeight() + textHeight;
            // 创建带白色背景的新图片(TYPE_INT_RGB 不含透明通道,背景为白)
            BufferedImage resultImage = new BufferedImage(120, 120, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = resultImage.createGraphics();
            // 设置白色背景
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, width, height);
            // 绘制插入的图片(顶部对齐)
            g2d.drawImage(overlayImage, 30, 10, null);
            // 设置文字样式
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.BLACK);
            g2d.setFont(new Font("Microsoft YaHei", Font.PLAIN, 18)); // 支持中文
            // 计算文字居中位置
            FontMetrics fm = g2d.getFontMetrics();
            int textWidth = fm.stringWidth(fileName);
            int x = (width - textWidth) / 2;
            int y = overlayImage.getHeight() + ((textHeight - fm.getHeight()) / 2) + fm.getAscent();
            // 绘制文字
            g2d.drawString(fileName, x, y);
            // 释放资源
            g2d.dispose();
            ImageIO.write(resultImage, "png", baos);
            return baos.toByteArray();
        }
    }

}

3. 默认附件图标

java 复制代码
public enum AttachmentIconEnum {

    DOCX("data:image/png;base64,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"),

    XLSX("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABXFJREFUeF7tW3tQVFUc/u7dxQU1bPJZoBLQDIWwV0EqnRo0iLKEQEbyQVpjCgnGkDkRwWypNWpOBiNPS0GzUEHy1eAjBcEnfzQp5oROWWg6IiEUk+De25xloL3cu487tevZ7v7+2/O49/d953e/3zlnz2GgcmNowx9qCJ/wvaHxvLP8umcERBoiPdvQwTFGgeMFhmNY6CGAA+DppfEYdtpwusMZJDiFgDBD2IjuuzzHsqyeFwSOIUAZTLAE0KUJ4Aycn5HX6hme5xgGnADTqPopGU2XIUCfow/mGU3viPaOqh7ASCVg5dpSR0BgXqBu8M1hHCMInMAwHCAQoGRkvf4tWOoICMqKGD7Io4eMqt4EtleYQhwBlBoN4HK4yUawWQwEDmAediZYuXf5hPrka7Wabkf5cRco/Ca++jJ5vikLEAJ4sGcc9UKlz/XV+4LVsEq7KWq/76VqFgwE1RLA8GzE3llVZ90EqPUTcEeA+xNwa4BbBKnNAiey6zBEN0SU12dWx/f/nhOUhLlBL9ud99+tz8G5VvEWA9Ui6CaAtghInbZENtwECCg6WmIxFCP8JyNs/CTZ+sKjxRb7URcBAaP8UZW2U+Jwj7EH4e8/YRFI+euboR8bKqr/804XlpSl4lyL5W0/6gggCFYlfICZ3AsSsBsO5mFzfZmkPCr4GaxPWispzz9SgE21n1kVMGcshhSLoE6rw5ncExLHr9++gZj1MyTlX6Zsw2MPPSoqP/tTIxaXpYLnedcjgHhMtCBl2mKJ82sOrMP2U1/1l88Kj0du7HuSdqnlaThx6aTN9EVlBPR53ZBdi6G6oSIQTVcvYG5xcn+Z3OhvaSjHJzWf2gRPGpSmFMFrkHi3jeTyPiPzgJARFjeVpdF4seK/mwcQHSB6MNBW7MhCzfmDSAxPQE5stqi6vasdcXkJaO+6bRcBVIqguecVqV8g6MEgEZi6H48jfVsG5JS/jxy70AOgnoCJ4zhsWSRV8jlF80HC39zqmxuwdOsye7Gb2lFPAHHy46Q1iA6OEgHb1Vhl+gTM7cUNcfi1reX/R8DI+0bg8Ns1VoEVHytFwbdFisCTxjHTn4VWqxX1M1/MKBHAvoc4ZDGUEZ2OV59aKAvwZmcrotbFKAZPOlCdBs0RLX8uE8lT5lkESTThwrUfFJPgEgQEjgpAZdoOq+AIeEKCUnOJT2Db4jKE+IonIycvn8KTAeLF0co9q0HEUYlRnwXkprpXbv2Csvpy5MZJp8DT10bj1h9tdnNANQFjho1BzVv7JWCI2lc27sb2lHKM9h4tSY8kEuw1qglYGW9A7MSZIizX2n/D7II56PyrE4uefg3pUUslWN/Ymo6GZulqUo4UagkgEx8yARpoGw7lYfPx3j0BDavB18uqMPYBX1EzIojzSxbAyBttBgKViyFvL28Q4Rs/fJwIwM+tV0wLHXMjqZGkyIGWf3gjNtV9bpMAKtNgZkwGFkz9Z8nbh8KSyu9O3wn/kf4SsPOKX8H5q01WSaCOgKmPTEFBcr7E6eYbl5C4MUkWzIzQ5/FR4ipJ3aGmI1hescJ1CPDQeKBkYSEmjZ8ocfrN7Zk4drHWIhi5uQJpvHLPh9jVWGmxH1UiaGlLnHhvbWub1D/uHyFLHKnb+91+tPwuv0qkigCbiuWABm4CaPtnyAGDbPWRqo8A6tKgsyPATYATzgkq/mvMmVHgjgB3BDj+qKz7E1D7OcF98dWmY8L9Z4WpOi4f7LOa9dDccZTwCsbu0gOzD1zvJ8D8Raq8MGGL6cD0QN3g+1VyZcYWGeb1qrk0pYQU7h3OzzhIJdfm7CVGVRcn7SXFzxDp6d3TwTGsCq7O2ksKaaeay9NKSHFk278BpaKbbiHMt1QAAAAASUVORK5CYII="),

    DEFAULT("data:image/jpeg;base64,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");

    private String icon;

    AttachmentIconEnum(String icon) {
        this.icon = icon;
    }

    public String getIcon() {
        return icon;
    }
}

4. 组装Ole对象,插入附件到word文档中

java 复制代码
import com.example.demo.example.AttachmentIconUtils;
import org.apache.poi.ooxml.POIXMLTypeLoader;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

public class AttachmentUtil {

    public static String attachmentFilePath = "C:\\Users\\PC\\Desktop\\test.xlsx";

    public static void main(String[] args) throws Exception {
        XWPFDocument doc = new XWPFDocument();
        // 创建段落
        XWPFParagraph p1 = doc.createParagraph();
        XWPFRun run1 = p1.createRun();
        // 设置超链接文本
        run1.setText("插入附件演示:");
        run1.setColor("0000FF");

        XWPFParagraph p2 = doc.createParagraph();
        XWPFRun run2 = p2.createRun();
        CTR ctr = run2.getCTR();
        File attachmentFile = new File(attachmentFilePath);
        //组装附件显示的图标
        byte[] attachmentIconByte = AttachmentIconUtils.getAttachmentIconByte(attachmentFile.getName());
        String imageRId = doc.addPictureData(attachmentIconByte,XWPFDocument.PICTURE_TYPE_PNG);
        //插入并组装附件结构
        String uuidRandom = UUID.randomUUID().toString().replace("-", "") + ThreadLocalRandom.current().nextInt(1024);
        String shapeId = "_x0000_i20" + uuidRandom;
        byte[] attachmentData = getAttachmentData(attachmentFile);
        String programId = "Package";
        String partNamePath = "/word/embeddings/oleObject1.bin";
        PackagePartName partName = PackagingURIHelper.createPartName(partNamePath);
        PackagePart packagePart = doc.getPackage().createPart(partName, "application/vnd.openxmlformats-officedocument.oleObject");
        try(OutputStream out = packagePart.getOutputStream()){
            out.write(attachmentData);
        }
        PackageRelationship ole = doc.getPackagePart().addRelationship(
                partName,
                TargetMode.INTERNAL,
                "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject");
        String embeddId = ole.getId();
        String wObjectXml = "<w:object xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"             xmlns:v=\"urn:schemas-microsoft-com:vml\"             xmlns:o=\"urn:schemas-microsoft-com:office:office\"             xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"   w:dxaOrig=\"1520\" w:dyaOrig=\"960\"><v:shape id=\"" + shapeId + "\" o:spt=\"75\" type=\"#_x0000_t75\" style=\"height:48.0pt;width:48.0pt;\" o:ole=\"t\" filled=\"f\" o:preferrelative=\"t\" stroked=\"f\" coordsize=\"21600,21600\"><v:fill on=\"f\" focussize=\"0,0\"/><v:stroke on=\"f\"/><v:imagedata r:id=\"" + imageRId + "\" o:title=\"\"/><o:lock v:ext=\"edit\" aspectratio=\"t\"/></v:shape><o:OLEObject Type=\"Embed\" ProgID=\"" + programId + "\" ShapeID=\"" + shapeId + "\" DrawAspect=\"Icon\" ObjectID=\"" + shapeId + "\" r:id=\"" + embeddId + "\" /></w:object>";
        Document document = DocumentHelper.readDocument(new InputSource(new StringReader(wObjectXml)));
        ctr.set((XmlObject)XmlObject.Factory.parse(document.getDocumentElement(), POIXMLTypeLoader.DEFAULT_XML_OPTIONS));

        //写入文件(输出到桌面)
        String desktopPath = System.getProperty("user.home") + File.separator + "Desktop/test";
        String outputPath = desktopPath + File.separator + "word_test_" + System.currentTimeMillis() + ".docx";
        try(FileOutputStream fileOutputStream = new FileOutputStream(outputPath)){
            doc.write(fileOutputStream);
        }
        System.out.println("文档已生成:" + outputPath);
        doc.close();
    }

    private static byte[] getAttachmentData(File attachmentFile) throws Exception {
        String templatePath = System.getProperty("user.dir") + "\\oleObject1.bin";
        String Ole10NativeKey = "\u0001Ole10Native";
        POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(templatePath));
        byte[] newData = createOle10Native(attachmentFile);
        fs.getRoot().getEntry(Ole10NativeKey).delete();
        try(ByteArrayInputStream bis = new ByteArrayInputStream(newData)) {
            fs.createOrUpdateDocument(bis,Ole10NativeKey);
        }
        try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            fs.writeFilesystem(baos);
            return baos.toByteArray();
        }
    }

    private static byte[] createOle10Native(File attachmentFile) throws IOException {
        String filePath = attachmentFile.getPath();
        String fileName = attachmentFile.getName();
        String tempFilePath = System.getProperty("java.io.tmpdir") + "\\" + fileName;
        FileInputStream fileInputStream = new FileInputStream(filePath);
        byte[] fileByte = fileInputStream.readAllBytes();
        int size = 33 + fileName.length() + filePath.length() + tempFilePath.length() + fileByte.length + 2 * fileName.length() + 2 * filePath.length() + 2 * tempFilePath.length();
        ByteBuffer buffer = ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN);
        // Version
        buffer.putInt(260); // Set to 0x00000101

        // Flags (usually 0)
        buffer.putShort((short)2);

        // fileName
        byte[] fileNameBytes = fileName.getBytes(StandardCharsets.ISO_8859_1);
        buffer.put(fileNameBytes);
        buffer.put((byte)0);

        // filePath
        byte[] filePathBytes = filePath.getBytes(StandardCharsets.ISO_8859_1);
        buffer.put(filePathBytes);
        byte[] bytes = new byte[]{0,0,0,3,0};
        buffer.put(bytes);

        // tempFilePath
        buffer.putInt(tempFilePath.length() + 1);
        byte[] temPathBytes = tempFilePath.getBytes(StandardCharsets.ISO_8859_1);
        buffer.put(temPathBytes);
        buffer.put((byte) 0);

        // file length
        buffer.putInt(fileByte.length);

        // File content
        buffer.put(fileByte);

        // 文件临时路径2长度
        buffer.putInt(tempFilePath.length());
        // 文件临时路径2
        for(int i = 0; i < tempFilePath.length(); i++) {
            buffer.put(temPathBytes[i]);
            buffer.put((byte)0);
        }

        // 文件名称2长度
        buffer.putInt(fileName.length());
        // 文件名称2
        for(int i = 0; i < fileName.length(); i++) {
            buffer.put(fileNameBytes[i]);
            buffer.put((byte)0);
        }

        // 文件路径2长度
        buffer.putInt(filePath.length());
        // 文件路径2
        for(int i = 0; i < filePath.length(); i++) {
            buffer.put(filePathBytes[i]);
            buffer.put((byte)0);
        }
        return buffer.array();
    }
}

5. 指定ole对象模板,执行main代码时,需要获取ole模板对象组装新的ole对象,模板下载,可在文章顶部下载即可

6. 展示效果

相关推荐
Donald_brian2 小时前
线程同步
java·开发语言·jvm
全栈陈序员2 小时前
【Python】基础语法入门(十五)——标准库精选:提升效率的内置工具箱
开发语言·人工智能·python·学习
全靠bug跑2 小时前
Nacos 入门实战:部署、服务注册与发现全指南
java·spring cloud·docker·nacos
郑州光合科技余经理2 小时前
技术视角:海外版一站式同城生活服务平台源码解析
java·开发语言·uni-app·php·排序算法·objective-c·生活
喵了meme2 小时前
Linux学习日记19:线程同步与互斥锁
java·jvm·学习
郑州光合科技余经理2 小时前
海外版生活服务系统源码 | 外卖+跑腿一站式平台技术解析
java·开发语言·javascript·git·spring cloud·php·生活
小小Fred2 小时前
Cortex-M3 LR寄存器的特殊值EXC_RETURN
java·开发语言·jvm
小小心愿家2 小时前
线程——对于锁的进一步认识
java·开发语言
曹牧2 小时前
Java: FATAL ERROR: processing of -javaagent failed
java·开发语言