什么是aspose?

Aspose是一套强大的文档处理工具,被超过80%的财富100强公司信赖,用于在应用程序中创建、编辑、导出和转换100多种文件格式。无论是PDF、Word文档、Excel表格还是PowerPoint演示文稿,Aspose都能轻松胜任。

我的需求:

word动态合同,加入用户信息、手签字、公章、骑缝章、word转pdf、隐私合同马赛克遮挡替换。

实现逻辑:

在不同位置加入书签,通过书签替换文本或者图片,根据页数分割公章,每页固定位置加入分好的公章,将word转pdf。

提前准备:

准备好一个word原始合同模板,在模板中加入书签,具体步骤:插入->书签->书签名->添加

Java代码aspose电子合同_Java

最后记得保存哟!

代码实现:
  1. 核心jar包
<dependency>

   <groupId>org.aspose</groupId>

   <artifactId>aspose-cells</artifactId>

   <version>8.5.2</version>

</dependency>

<dependency>

   <groupId>org.aspose</groupId>

   <artifactId>aspose-words</artifactId>

   <version>19.5</version>

</dependency>
  1. 具体代码如下,已经过测试
package zf;

import cn.hutool.core.collection.CollectionUtil;
import com.aspose.words.*;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zf.academic.constant.EmpowerConst;
import com.zf.academic.utils.SealUtil;
import com.zf.common.exception.base.BaseException;
import com.zf.common.utils.DateUtil;
import org.apache.commons.io.FileUtils;
import wordUtil.LicenseLoad;

import javax.annotation.Nullable;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhangfan
 */
public class AddSeal {

    static String mosaic = "D:\\ok.png";
    static byte[] base643en = Base64.getDecoder().decode(EmpowerConst.MARK_BASE64);

    static Map<String, String> map = new HashMap<>();
    static Map<String, String> mosaicTag = new HashMap<>();
    static String userName = "展亚鹏";
    static String worksName = "补单后续";
    static String contractNo = "";
    static Date startDate = DateUtil.getYdDate("2024-12-29");
    //合同日期只有年
    static boolean isOnlyYear = true;
    // 是否少量遮挡开关
    static boolean littleMark = true;
//    static String empowerDetail = "在 经生论与经无理 发表 张三 的《 我爱说实话论及其在企业中的运用 》,出版时间 2001-02-18;";
//    static String empowerPeriod = "5";

    // 作者实际签字日期
//    static String authorSignDate = "29";
    //    static String buyoutAmount = "1000";
    static String year = DateUtil.getYear(startDate);
    //    static String month = DateUtil.getYearMm(startDate);
//    static String day = DateUtil.getYearDd(startDate);
    static String templatePath = "D:\\download\\1.doc";
    static String empowerType = EmpowerConst.BUY_OUT;
    static String signaturePath = "C:\\Users\\zf176\\Desktop\\2.jpg";
    static String targetPath = "D:\\1.doc";
    static String sealPath = "D:\\seal.png";

//    static String empowerTimeSegment = buildTimeSegment(startDate);

//    private static String buildTimeSegment(Date startDate) {
//        StringBuilder builder = new StringBuilder();
//        if (ObjectUtil.isNotEmpty(startDate)) {
//            Date endDate = DateUtil.addDays(DateUtil.addYears(startDate, Integer.parseInt(empowerPeriod)), -1);
//            builder.append("( ");
//            builder.append(com.zf.common.utils.DateUtil.parseDateToStr("yyyy-MM-dd", startDate));
//            builder.append(" 至 ");
//            builder.append(com.zf.common.utils.DateUtil.parseDateToStr("yyyy-MM-dd", endDate));
//            builder.append(" )");
//        }
//        return builder.toString();
//    }


    public static void main(String[] args) throws Exception {
        Map<String, String> fileTag = buildPrivacyContractTag();
        Map<String, String> mosaicTag = builderMosaicTag();
        toSignature(templatePath, empowerType, sealPath, targetPath, sealPath, fileTag, mosaicTag);
        wordToPdf(targetPath);
//        pdfToWord("C:\\Users\\zf176\\Desktop\\2.pdf");

    }


    private static void wordToPdf(String wordId) throws Exception {
        LicenseLoad.getLicense();
        File file = new File("D:" + File.separator + userName + "-"
                + worksName
                + EmpowerConst.FILE_PDF_TYPE);
        FileOutputStream out = new FileOutputStream(file);
        Document doc = new Document(wordId);
        doc.save(out, SaveFormat.PDF);
    }

    private static void pdfToWord(String wordId) throws Exception {
        LicenseLoad.getLicense();
        File file = new File("D:" + File.separator + userName + "-"
                + worksName
                + EmpowerConst.FILE_DOC_TYPE);
        FileOutputStream out = new FileOutputStream(file);
        Document doc = new Document(wordId);
        doc.save(out, SaveFormat.DOC);
    }

    /**
     * pdf完整合同
     *
     * @return
     */
    private static Map<String, String> builderContractDate() {
        map.put(EmpowerConst.YEAR, year);
//        map.put("month", month);
//        map.put("day", day);
//        map.put(EmpowerConst.YEAR2, year);
//        map.put("month2", month);
//        map.put("day2", day);
//        map.put(EmpowerConst.YEAR3, year);
//        map.put("month3", month);
//        map.put("day3", day);
//        map.put(EmpowerConst.YEAR4, year);
//        map.put("month4", month);
//        map.put("day4", day);
        return map;
    }

    /**
     * 隐私合同
     *
     * @return
     */
    private static Map<String, String> buildPrivacyContractTag() {

//        map.put(EmpowerConst.OWNER, userName);
//        map.put(EmpowerConst.OWNER1, userName);
//        map.put(EmpowerConst.OWNER2, userName);
        if (isOnlyYear) {
            map.put(EmpowerConst.CONTRACT_NO, contractNo);
            map.put(EmpowerConst.YEAR, year);
            map.put(EmpowerConst.YEAR2, year);
            map.put(EmpowerConst.YEAR3, year);
            map.put(EmpowerConst.YEAR4, year);
        }
//        map.put(EmpowerConst.CONTRACT_NO, contractNo);
//        map.put(EmpowerConst.PRODUCTION, worksName);
//        map.put(EmpowerConst.PRODUCTION2, worksName);

        // 构建少量遮挡参数
//        if (littleMark) {
//            map.put(EmpowerConst.MONTH, month);
//            map.put(EmpowerConst.MONTH2, month);
//            map.put(EmpowerConst.MONTH3, month);
//            map.put(EmpowerConst.MONTH4, month);
//            map.put(EmpowerConst.DAY, day);
//            map.put(EmpowerConst.DAY2, day);
//            map.put(EmpowerConst.DAY3, day);
//            map.put(EmpowerConst.DAY4, day);
//            map.put(EmpowerConst.BUY_OUT_AMOUNT, buyoutAmount);
//            map.put(EmpowerConst.BUY_OUT_AMOUNT2, MoneySwitch.toChinese(buyoutAmount));
//            map.put(EmpowerConst.EMPOWER_PERIOD, empowerPeriod);
//            map.put(EmpowerConst.EMPOWER_PERIOD1, empowerTimeSegment);
//            map.put(EmpowerConst.PRODUCTION_DETAIL, empowerDetail);
//        }
        return map;
    }

    private static Map<String, String> builderMosaicTag() {
        mosaicTag.put(EmpowerConst.OWNER, userName);
        mosaicTag.put(EmpowerConst.OWNER1, userName);
        mosaicTag.put(EmpowerConst.OWNER2, userName);
        mosaicTag.put(EmpowerConst.PRODUCTION, worksName);
        mosaicTag.put(EmpowerConst.PRODUCTION2, worksName);
        return mosaicTag;
    }


    public static void toSignature(String wordId, String empowerType, String picture, String fullWordFile, String sealPath, Map<String, String> tag, Map<String, String> wordTag) throws Exception {
        if (StringUtils.isBlank(wordId)) {
            throw new BaseException("数据错误!授权后的doc文件ID为空");
        }
        File destFile = new File(fullWordFile);
        File file = new File(wordId);
        String newPath = destFile.getPath();
        FileUtils.copyFile(file, destFile);
        LicenseLoad.getLicense();
        Document doc = new Document(newPath);
        DocumentBuilder builder = new DocumentBuilder(doc);
        BookmarkCollection bookmarks = doc.getRange().getBookmarks();
        if (CollectionUtil.isNotEmpty(tag)) {
            for (Map.Entry<String, String> entry : tag.entrySet()) {
                String key = entry.getKey();
                if (builder.moveToBookmark(key)) {
                    builder.write(entry.getValue());
                    bookmarks.remove(key);
                }
            }
        }
        // 单个字换打码图
        if (CollectionUtil.isNotEmpty(wordTag)) {
            for (Map.Entry<String, String> entry : wordTag.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (builder.moveToBookmark(key) && StringUtils.isNotBlank(value)) {
                    int mosaticSize = value.length() - 1;
                    String surname = value.substring(0, 1);
                    builder.write(surname);
                    for (int j = 0; j < mosaticSize; j++) {
                        builder.insertImage(base643en, 18, 15);
                    }
                    bookmarks.remove(key);
                }
            }
            int length = userName.length();
            if (builder.moveToBookmark(EmpowerConst.SIGNATURE_OF_PARTY_A)) {
                for (int i = 0; i < length; i++) {
                    builder.insertImage(Base64.getDecoder().decode(EmpowerConst.SIGN_BASE64), 80D, 100D).setWrapType(WrapType.INLINE);
                }
                bookmarks.remove(EmpowerConst.SIGNATURE_OF_PARTY_A);
            }
            //附件 二次写入签字区域
            if (builder.moveToBookmark(EmpowerConst.SIGNATURE_OF_PARTY_B)) {
                for (int i = 0; i < length; i++) {
                    builder.insertImage(Base64.getDecoder().decode(EmpowerConst.SIGN_BASE64), 80D, 100D).setWrapType(WrapType.INLINE);
                }
                bookmarks.remove(EmpowerConst.SIGNATURE_OF_PARTY_B);
            }
        } else {
            if (builder.moveToBookmark(EmpowerConst.SIGNATURE_OF_PARTY_A)) {
                Shape shape = builder.insertImage(picture, 245D, 130D);
                shape.setWrapType(WrapType.NONE);
                bookmarks.remove(EmpowerConst.SIGNATURE_OF_PARTY_A);
            }
            //附件 二次写入签字区域
            if (builder.moveToBookmark(EmpowerConst.SIGNATURE_OF_PARTY_B)) {
                Shape shape = builder.insertImage(picture, 245D, 130D);
                shape.setWrapType(WrapType.NONE);
                bookmarks.remove(EmpowerConst.SIGNATURE_OF_PARTY_B);
            }
        }
        if (builder.moveToBookmark(EmpowerConst.PUBLIC_SEAL)) {
            Shape shape = builder.insertImage(sealPath, 150D, 150D);
            shape.setWrapType(WrapType.NONE);
            bookmarks.remove(EmpowerConst.PUBLIC_SEAL);
        }
        doc.save(newPath);
        buildCrossPageSeal(newPath, sealPath);
//        if(EmpowerConst.PRO_RATA.equals(empowerType)){
////        SealUtil.addNewLine(newPath);
//        }
        File filePath = new File(picture);
//        if (filePath.exists()) {
//            filePath.delete();
//        }
    }

    public static void goMosaicSignature(String wordId, String empowerType, String picture, String fullWordFile, String sealPath, @Nullable Map<String, String> tag, Map<String, String> wordTag) throws Exception {
        if (StringUtils.isBlank(wordId)) {
            throw new BaseException("数据错误!授权后的doc文件ID为空");
        }
        File destFile = new File(fullWordFile);
        File file = new File(wordId);
        String newPath = destFile.getPath();
        FileUtils.copyFile(file, destFile);
        LicenseLoad.getLicense();
        Document doc = new Document(newPath);
        DocumentBuilder builder = new DocumentBuilder(doc);
        BookmarkCollection bookmarks = doc.getRange().getBookmarks();
        if (CollectionUtil.isNotEmpty(tag)) {
            for (Map.Entry<String, String> entry : tag.entrySet()) {
                String key = entry.getKey();
                if (builder.moveToBookmark(key)) {
                    builder.write(entry.getValue());
                    bookmarks.remove(key);
                }
            }
        }

        if (builder.moveToBookmark(EmpowerConst.SIGNATURE_OF_PARTY_A)) {
            Shape shape = builder.insertImage(picture, 245D, 130D);
            shape.setWrapType(WrapType.NONE);
            bookmarks.remove(EmpowerConst.SIGNATURE_OF_PARTY_A);
        }
        if (builder.moveToBookmark(EmpowerConst.PUBLIC_SEAL)) {
            Shape shape = builder.insertImage(sealPath, 150D, 150D);
            shape.setWrapType(WrapType.NONE);
            bookmarks.remove(EmpowerConst.PUBLIC_SEAL);
        }
        //附件 二次写入签字区域
        if (builder.moveToBookmark(EmpowerConst.SIGNATURE_OF_PARTY_B)) {
            Shape shape = builder.insertImage(picture, 245D, 130D);
            shape.setWrapType(WrapType.NONE);
            bookmarks.remove(EmpowerConst.SIGNATURE_OF_PARTY_B);
        }
        doc.save(newPath);
        buildCrossPageSeal(newPath, sealPath);
//        if(EmpowerConst.PRO_RATA.equals(empowerType)){
////        SealUtil.addNewLine(newPath);
//        }
        File filePath = new File(picture);
//        if (filePath.exists()) {
//            filePath.delete();
//        }
    }


    /**
     * 加入骑缝章
     *
     * @param filePath 文件路径
     * @param sealPath 工章路径
     */
    public static void buildCrossPageSeal(String filePath, String sealPath) throws Exception {
        if (StringUtils.isBlank(filePath) || StringUtils.isBlank(sealPath)) {
            throw new BaseException("合同加入骑缝章发生错误,参数为空");
        }
        Document doc;
        float y;
        int num;
        DocumentBuilder builder;
        LayoutCollector layoutCollector;
        LicenseLoad.getLicense();

        InputStream inputStream = Files.newInputStream(Paths.get(filePath));
        doc = new Document(inputStream);
        builder = new DocumentBuilder(doc);
        num = doc.getPageCount();
        layoutCollector = new LayoutCollector(doc);
        doc.updatePageLayout();
        float widthInPoints = doc.getPageInfo(0).getWidthInPoints();
        float heightInPoints = doc.getPageInfo(0).getHeightInPoints();
        y = heightInPoints / 2 - 100;
        int sealCross = 150 / num;
        float left = widthInPoints - sealCross;
        BufferedImage[] images = SealUtil.splitSeal(sealPath, 1, num);
        NodeCollection runs = doc.getChildNodes(NodeType.PARAGRAPH, true);
        int tempPage = 0;
        for (int i = 0; i < runs.getCount(); i++) {
            Node r = runs.get(i);
            int numPage = layoutCollector.getStartPageIndex(r);
            if (numPage != tempPage) {
                builder.moveTo(r);
                builder.insertImage(images[numPage - 1], 1, left, 1, y, sealCross - 2, 150, WrapType.NONE);
                doc.save(filePath);
            }
            tempPage = numPage;
        }

    }


}
官方文档:

Aspose.Words for Java|文档

除上述外Aspose.Words还提供

  • 邮件合并:邮件合并是Aspose.Words的核心功能之一,可以在Word模板中定义邮件合并区域,使用Java代码填充数据源,大批量生成自定义Word文件。相关API主要有:MailMerge、MergeField 等。
  • 比较文档:Aspose.Words提供比较两个文档差异的功能,可以生成详细的HTML格式比较报告。使用Document.compare()方法传入要比较的两个Document对象即可。
  • 搜索与替换:Aspose.Words提供丰富的搜索与替换功能,可以按内容、格式、样式等条件搜索与替换,使用FindReplaceOptions设置选项,调用Document.getRange().replace()方法替换。
  • 文档保护:可以使用ProtectionType枚举设置文档保护类型(如只读、注释等),并用Document.protect()方法进行保护。使用密码可以解除保护。
  • 文档版本控制:可以使用Document.startTrackRevisions()开启修订,修改后调用Document.stopTrackRevisions()停止修订。之后就可以使用比较方法比较不同版本的修订情况。
  • PDF & HTML导入导出:可以将Word文档导入/导出为PDF或HTML格式。
  • 文档编辑限制:可以限制文档的编辑、打印等功能。使用EditRestriction类型进行设置。
  • 自定义XML:Aspose.Words提供丰富的自定义XML功能,可以定义XML元素与属性,进行导入导出及操作。
  • 文档优化:提供清理未使用的样式、列出文档中的所有样式、检测潜在问题等优化功能。
  • 文档转换:可以方便地在Word文档与其他格式(PDF, HTML等)之间转换
  • 插件:Aspose还提供Excel公式、PDF阅读器、图片处理等插件,可插入到Word文档中使用。