使用合并文档时想要让字体保持一致但是不生效

您好 我使用如下的代码进行文档的合并 关于字体的尝试我试了很多但是并不生效

public static Document addDocument(String key,Document mainDoc,Document addDoc,Boolean isPortrait) {
    try{

        FontSettings fontSettings = new FontSettings();
        fontSettings.setFontsFolder("/usr/share/fonts",true);
        mainDoc.setFontSettings(fontSettings);
        addDoc.setFontSettings(fontSettings);
        DocumentBuilder Builder = new DocumentBuilder(mainDoc);
        DocumentBuilder addBuilder = new DocumentBuilder(mainDoc);
        Range range = mainDoc.getRange();
        NodeCollection runs = mainDoc.getChildNodes(NodeType.PARAGRAPH, true); //获取所有节点
        addBuilder.getFont().setName("仿宋");
        addDoc.save(addDoc.getOriginalFileName());
        int dell = 0 ;
        for (int i = 0; i < runs.getCount(); i++) {
            Paragraph r = (Paragraph) runs.get(i);
            String text = r.getRange().getText();//获取段落文本
            if(text.length()>=key.length() && text.indexOf(key)>=0) {
                //指定段落插入表格

                Builder.getPageSetup().setPaperSize(PaperSize.A4);
                Section currentSection = Builder.getCurrentSection();
                if (isPortrait){
                    currentSection.getPageSetup().setOrientation(Orientation.PORTRAIT);

                }
                else {
                    currentSection.getPageSetup().setOrientation(Orientation.LANDSCAPE);

                }
                Builder.moveTo(r);
                Node insertAfterNode = Builder.getCurrentParagraph().getPreviousSibling();
                insertDocumentAfterNode(insertAfterNode, mainDoc , addDoc);
                r.remove();//删除标记所在行
                break;
            }
        }
        return mainDoc;
    }catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

private static void insertDocumentAfterNode(Node insertAfterNode, Document mainDoc, Document srcDoc) throws Exception  {
    if (insertAfterNode.getNodeType() != 8 && insertAfterNode.getNodeType() != 5) {
        throw new Exception("The destination node should be either a paragraph or table.");
    }else {
        CompositeNode dstStory = insertAfterNode.getParentNode();
        Body body = srcDoc.getLastSection().getBody();
        while (null != body.getLastParagraph() && !body.getLastParagraph().hasChildNodes()){
            srcDoc.getLastSection().getBody().getLastParagraph().remove();
        }
        body.getFirstParagraph().getParagraphFormat().setSpaceBefore(0);
        body.getLastParagraph().getParagraphFormat().setSpaceAfter(0);
        NodeImporter importer = new NodeImporter(srcDoc, mainDoc, ImportFormatMode.KEEP_DIFFERENT_STYLES);
        int sectCount = srcDoc.getSections().getCount();

        for (int sectIndex = 0; sectIndex < sectCount; ++sectIndex){
            Section srcSection = srcDoc.getSections().get(sectIndex);
            int nodeCount = srcSection.getBody().getChildNodes().getCount();
            for (int nodeIndex = 0; nodeIndex < nodeCount; ++nodeIndex){
                Node srcNode = srcSection.getBody().getChildNodes().get(nodeIndex);
                Node newNode = importer.importNode(srcNode, true);
                dstStory.insertAfter(newNode, insertAfterNode);
                insertAfterNode = newNode;
            }
        }
    }
}

需要合并的两个文本如下
adddoc.docx (5.6 KB)

maindoc.docx (29.5 KB)
addDocument 的参数key 是maindoc中的“+brief_overview” 我想让adddoc中的文档保持maindoc中的文档中的字体格式 也就是宋体,但这总是不生效。希望能够得到解答

@JIYO_SANG 为什么不使用内置的 DocumentBuilder.insertDocument 方法?另外,请尝试使用 ImportFormatMode.KEEP_SOURCE_FORMATTING

这个方法可以做到将文档中的人为规定的占位符替换为需要插入的文档吗,如果可以,请教我相应的代码

@JIYO_SANG 您可以使用 IReplacingCallback 来实现这一点。例如,请看以下代码:

Document doc = new Document("C:\\Temp\\dst.docx");
FindReplaceOptions opt = new FindReplaceOptions();
opt.setReplacingCallback(new ReplaceWithDocumentCallback());
doc.getRange().replace("[PLACEHOLDER]",  "C:\\Temp\\src.docx", opt);
doc.save("C:\\Temp\\out.docx");
public class ReplaceWithDocumentCallback implements IReplacingCallback {
    
    /**
     * This method is called by the Aspose.Words find and replace engine for each match.
     */
    @Override
    public int replacing(ReplacingArgs e) throws Exception {
        
        Document doc = (Document)e.getMatchNode().getDocument();
        
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.getMatchNode();
        
        // The first (and may be the only) run can contain text before the match,
        // in this case it is necessary to split the run.
        if (e.getMatchOffset() > 0)
            currentNode = splitRun((Run)currentNode, e.getMatchOffset());
        
        // This array is used to store all nodes of the match for further deleting.
        ArrayList<Run> runs = new ArrayList<Run>();
        
        // Find all runs that contain parts of the match string.
        int remainingLength = e.getMatch().group().length();
        while (
                remainingLength > 0 &&
                        currentNode != null &&
                        currentNode.getText().length() <= remainingLength)
        {
            runs.add((Run)currentNode);
            remainingLength -= currentNode.getText().length();
            
            // Select the next Run node.
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do
            {
                currentNode = currentNode.getNextSibling();
            } while (currentNode != null && currentNode.getNodeType() != NodeType.RUN);
        }
        
        // Split the last run that contains the match if there is any text left.
        if (currentNode != null && remainingLength > 0)
        {
            splitRun((Run)currentNode, remainingLength);
            runs.add((Run)currentNode);
        }
        
        // Create DocumentBuilder to insert HTML.
        DocumentBuilder builder = new DocumentBuilder(doc);
        // Move builder to the first run.
        builder.moveTo(runs.get(0));
        builder.insertDocument(new Document(e.getReplacement()), ImportFormatMode.KEEP_SOURCE_FORMATTING);
        
        Paragraph currentParagraph = builder.getCurrentParagraph();
        // Delete matched runs
        for (Run run : runs)
            run.remove();
        // Remove current paragraph if it is empty.
        if(!currentParagraph.hasChildNodes())
            currentParagraph.remove();
        
        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.SKIP;
    }
    
    private static Run splitRun(Run run, int position)
    {
        Run afterRun = (Run)run.deepClone(true);
        run.getParentNode().insertAfter(afterRun, run);
        afterRun.setText(run.getText().substring(position));
        run.setText(run.getText().substring(0, position));
        return afterRun;
    }
}

请问如果基于您提供的代码,我该如何像之前一样通过传入参数自由控制插入那一页页面所在的方向呢

@alexey.noskov 首先感谢您的帮助!您提供的代码在合并上是生效的,但依然没能解决字体的问题,这是否与服务器上的字体有关?我需要考虑调用aspose中字体相关的api吗

@JIYO_SANG 您的输出格式是什么?当文档呈现为固定页面格式(例如 PDF)时,需要字体。

1 Like

输出格式是docx,当我用两个宋体(SIM SUN)字体尝试合并时 似乎也会出现这个问题

@JIYO_SANG 您是否尝试过使用这样的代码进行简单的文档连接?

Document dst = new Document("C:\\Temp\\dst.docx");
Document src = new Document("C:\\Temp\\src.docx");
dst.appendDocument(src, ImportFormatMode.KEEP_SOURCE_FORMATTING);
dst.save("C:\\Temp\\out.docx");
1 Like

是的,他们在简单的合并上出现了同样的问题

@JIYO_SANG
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): WORDSNET-28216

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

@alexey.noskov 请问 是否可以强制指定某种字体以暂时回避目前遇到的情况

@JIYO_SANG 该问题目前正在分析中,因此我们无法为您提供解决方法。我们会及时向您通报最新情况,并在问题解决或获得更多信息后告知您。对于由此造成的不便,敬请谅解。