aspose.word 20 java 替换占位符为文字或图片

以前写过用asposeword 替换文字和图片,但是后来遇到问题,有些word替换替换图片后会导致打开时弹出错误:此文件中检测到错误,单word可以通过进行一下修复来打开文件。

考虑可能是版本有bug,于是从官网下了最新的20.7版本。

下载:aspose word for java 20.7

新版替换字符为图片的方法有些不一样

使用方法:

package xf.test;

import com.aspose.words.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class TestAspose {
    public static void main(String[] args) {
        try {

             //doc 和docx 都是可以的
            Map<String,String>pmap = new HashMap<String,String>();
            pmap.put("[编写签名区域]","$pic:D:/javatest/sign2.png");
            pmap.put("$编号$","BH12345");
            //replace("D:/javatest/test删除图片.doc","D:/javatest/aspose测试删除图片.doc",pmap);
//            replace("D:/javatest/田清单A8.docx","D:/javatest/aspose测试删除图片.docx",pmap);
            replace("D:/javatest/aspose测试删除图片.docx","D:/javatest/aspose测试删除图片2.docx",pmap);

    }catch (Exception e){
        e.printStackTrace();
    }
    }



    public static boolean replace(String path, String outPath, Map<String,String> paramMap){
        if(path == null || path.isEmpty()) return false;
        if(outPath == null || outPath.isEmpty()) return false;
        if(paramMap == null || paramMap.isEmpty()) return false;
        try {
            Document doc = new Document(path);
            Iterator<String> paramKey = paramMap.keySet().iterator();
            while(paramKey.hasNext()){
                String key = paramKey.next();
                String v = paramMap.get(key);
                if(v.startsWith("$pic:")){
                    v = v.substring(5);
                    //如果key已经被替换成图片了,那就要将图片替换成新的图片,相当于重新插入图片
                    NodeCollection shapeCollection = doc.getChildNodes(NodeType.SHAPE, true);
                    Iterator<Shape>  shapeIterate =  shapeCollection.iterator();
                    java.util.List<Shape> shaplist = new ArrayList<Shape>();
                    while(shapeIterate.hasNext()){
                        Shape shape = shapeIterate.next();
                        if(key.equals(shape.getName())){
                            shaplist.add(shape);
                        }
                    }
                    DocumentBuilder builder = new DocumentBuilder(doc);
                    for(int i=0;i<shaplist.size();i++){
                        Shape shape = shaplist.get(i);
                        //将光标移动到指定节点
                        builder.moveTo(shape);
                        Shape img = builder.insertImage(v);
                        img.setName(key);
                        System.out.println("replace" +key);
                        shape.remove();
                    }
                    //替换文字为图片
                    doc.getRange().replace(key, "", new FindReplaceOptions(new ReplaceAndInsertImage(v,key)));
                }else{
                    doc.getRange().replace(key,v);
                }
            }
            doc.save(outPath);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }
}


class ReplaceAndInsertImage implements IReplacingCallback {
    private String url;
    private String name;
    public ReplaceAndInsertImage(String url,String name){
        this.url = url;
        this.name = name;
    }
    @Override
    public int replacing(ReplacingArgs e) throws Exception {
        //获取当前节点
        Node currentNode = e.getMatchNode();
        //节点拆分处理当前匹配字段
        splitRun(currentNode,e.getMatchOffset());
        //获取当前文档
        Document document =  (Document) currentNode.getDocument();
        DocumentBuilder builder = new DocumentBuilder(document);
        //将光标移动到指定节点
        builder.moveTo(currentNode);
        //插入图片
        Shape img = builder.insertImage(url);
        img.setName(name);
        return ReplaceAction.SKIP;
    }
    private void splitRun(Node currentNode ,int position){
        String text =  currentNode.getText();
        Node newNode = currentNode.deepClone(true);
        if(text.length() >= position+this.name.length()){
            ((Run)currentNode).setText (text.substring(position+this.name.length()));
        }else{
            int morlength = position+this.name.length() - text.length();
            ((Run)currentNode).setText ("");
            Node tmpnode = currentNode;
            for(int i=0;i<this.name.length();i++){
                System.out.println(i);
                tmpnode = tmpnode.getNextSibling();
                String tmptext= tmpnode.getText();
                System.out.println(tmptext);
                System.out.println(morlength);
                System.out.println("--------"+(tmptext.length() >= morlength));

                if(tmptext.length() >= morlength){
                    ((Run)tmpnode).setText(tmptext.substring(morlength));
                    break;
                }else{
                    morlength = morlength - tmptext.length();
                    ((Run)tmpnode).setText("");
                }
            }
        }
        if(position>0){
            ((Run)newNode).setText(text.substring(0, position));
            currentNode.getParentNode().insertBefore(newNode, currentNode);
        }
    }
}

20200813更新:原方法处理doc时存在bug,替换占位符为图片后,图片不是在占位符所在的位置,而是在占位符所在的node的起始位置,增加splitRun方法分割node节点。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心怀寰宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值