You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EA JavaScript生成RTF文件时提示"Failed to save the output file"的问题解决咨询

EA JavaScript生成RTF文件时提示"Failed to save the output file"的问题解决咨询

我目前遇到一个Enterprise Architect(EA)脚本的问题,想请大家帮忙分析解决:

我需要把EA项目里的图表导出到一个无法用EA直接生成的外部Word文档中,其他编辑这个Word的人也不需要有EA项目权限。我的做法是写了一段EA JavaScript脚本,给每个图表生成单独的RTF文件,然后在主Word文档里通过链接插入这些RTF。

一开始一切正常,但过了一段时间后,运行docGenerator.SaveDocument时会弹出**"Failed to save the output file"**的错误。我排查后发现:

  • 只有当这些RTF文件被Word文档作为链接引用后,才会出现保存失败的情况;如果不把RTF链接到Word,我可以无限次重新生成RTF
  • 我从来没有直接用Word打开过这些RTF文件(怕Word锁定文件),而且生成RTF时主Word文档也是关闭的
  • 之前用其他工具生成RTF并做同样的链接操作时,完全没有这个问题,所以我怀疑是EA的RTF生成机制导致的文件锁定或保护问题

我的核心需求是:

  1. 如何绕过EA在保存RTF时的文件保护,成功覆盖被Word链接引用过的RTF文件?
  2. 有没有其他EA的API或方法可以替代docGenerator.SaveDocument来导出图表为RTF?

以下是我当前脚本中生成RTF的关键代码片段:

function OnProjectBrowserScript()
{
    // Get the type of element selected in the Project Browser
    var treeSelectedType = Repository.GetTreeSelectedItemType();
    switch ( treeSelectedType )
    {
        case otPackage :
        {
            // Code for when a package is selected
            // [...] 省略其他逻辑
            packageDiagrams = thePackage.Diagrams; // Collection of all the Diagrams
            
            for ( var i = 0 ; i < packageDiagrams.Count ; i++ ) {
                var currentDiagram as EA.Diagram;
                currentDiagram = packageDiagrams.GetAt( i );
            
                // Document Generation using docGenerator
                var docGenerator as EA.DocumentGenerator;
                docGenerator = Repository.CreateDocumentGenerator();
                docGenerator.NewDocument("")
                docGenerator.DocumentDiagram(currentDiagram.DiagramID,1,"Diagram Report");
                var diagramName = currentDiagram.Name + ".rtf";

                //Save diagram into rtf document
                var saveSuccess = docGenerator.SaveDocument( diagramName, EA.DocumentType.dtRTF );
                if ( saveSuccess ) {
                    Session.Prompt( "Documentation complete!", promptOK );
                } else {
                    // -- > Error message saying file cannot be saved <--
                    Session.Prompt( "Error saving file " + diagramName + " : " + docGenerator.GetLastError(), promptOK );
                }
            
            }
            break;
        }
        // [...] 省略其他分支
    }
}

我自己梳理的可能解决方案方向,也想听听大家的建议

1. 优化文件处理和资源释放逻辑

EA的DocumentGenerator可能没有彻底释放文件资源,导致后续覆盖时被锁定。可以尝试:

  • 生成RTF前,先检查目标文件是否存在,若存在则尝试先删除(用FileSystemObject处理,捕获锁定异常)
  • 每次循环结束后显式销毁docGenerator对象,强制释放资源
  • 始终使用完整路径保存文件,避免EA默认路径的权限或缓存问题

示例代码片段:

// 引入文件系统对象
var fso = new ActiveXObject("Scripting.FileSystemObject");
// 获取EA模型的根路径,确保导出路径固定
var modelRootPath = Repository.GetModelPath();

for ( var i = 0 ; i < packageDiagrams.Count ; i++ ) {
    var currentDiagram = packageDiagrams.GetAt( i );
    var diagramName = currentDiagram.Name + ".rtf";
    var fullSavePath = modelRootPath + diagramName;

    // 先尝试删除旧文件(如果未被锁定)
    if (fso.FileExists(fullSavePath)) {
        try {
            fso.DeleteFile(fullSavePath, true);
        } catch(e) {
            Session.Prompt("无法覆盖旧文件:" + fullSavePath + ",错误:" + e.message, promptOK);
            continue;
        }
    }

    // 文档生成逻辑
    var docGenerator = Repository.CreateDocumentGenerator();
    docGenerator.NewDocument("")
    docGenerator.DocumentDiagram(currentDiagram.DiagramID,1,"Diagram Report");
    
    var saveSuccess = docGenerator.SaveDocument( fullSavePath, EA.DocumentType.dtRTF );
    if ( saveSuccess ) {
        Session.Prompt( "Documentation complete!", promptOK );
    } else {
        Session.Prompt( "Error saving file " + fullSavePath + " : " + docGenerator.GetLastError(), promptOK );
    }

    // 显式销毁对象
    docGenerator = null;
}

2. 换用直接导出图表的API替代DocumentGenerator

EA提供了Diagram.Export方法,可以直接导出图表为RTF,跳过文档生成的流程,可能避免文件锁定问题:

var fullSavePath = modelRootPath + currentDiagram.Name + ".rtf";
// 直接导出图表为RTF
var exportSuccess = currentDiagram.Export(
    fullSavePath, 
    "RTF", 
    1, // 导出质量(1为最高)
    0, 0, // 宽度高度设为0表示使用图表原始尺寸
    true, // 是否包含图例
    false // 是否导出为黑白
);

if (exportSuccess) {
    Session.Prompt("图表导出成功:" + fullSavePath, promptOK);
} else {
    Session.Prompt("图表导出失败:" + fullSavePath, promptOK);
}

这个方法生成的RTF是纯图表内容,和DocumentGenerator生成的带"Diagram Report"模板的RTF格式有差异,但更轻量化,适合只需要插入图表的场景。

3. 排查Word的后台缓存锁定

虽然关闭了主Word,但Word可能在后台保留了链接文件的缓存句柄。可以尝试:

  • 生成RTF前,结束所有WINWORD.EXE进程,确保没有残留的文件锁定
  • 将RTF导出到一个独立的、非Word默认访问的目录,避免Word的自动缓存机制影响

备注:内容来源于stack exchange,提问作者lctdim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:44:29