关于文档的权限问题

我想给我的DOCX或DOC文档添加一些权限,比禁止编辑,禁止复制,禁止另存,禁止打印等等,这些在PDF那里很好设置,但是DOCX文档这边却没有,我只找到了禁止编辑的设置,但是其他的却没有相关设置,请问一下这些权限是可以设置的吗,或者说有方法可以实现这些权限吗,使用VBA宏的话也可以考虑

@wslioy

请问您希望使用哪个Aspose产品来设置DOCX文档的权限?

我这边使用的是 words-java,操作的是docx或doc的文档文件

@wslioy 遗憾的是,Aspose.Words 和 MS Word 一样不提供复制、保存或打印限制。 请查看我们的文档:

这些限制确实很难实现,只能想想其他方法。我在想是不是能使用VBA宏来实现,我在使用VBA宏时遇到了一个问题,就是我在docx文档上写入宏,宏中存在中文的字符串会变成???,导致字符串部分匹配异常,这个估计是编码问题,但是保存的时候没有编码相关的配置。

VbaProject vbaProject = new VbaProject();
vbaProject.setName("VBAProject");
VbaModule vbaModule = vbaProject.getModules().get("ThisDocument");
vbaModule.setType(VbaModuleType.DOCUMENT_MODULE);
vbaModule.setSourceCode(sourceCode);

sourceCode中的中文会全部变成???

@wslioy 遗憾的是,很难说如何在 MS Word 中进行更改。 您可以查看 microsoft link,如果系统语言不是中文,则尝试更改系统语言,或者尝试使用其他 MS Word 属性进行更改。

我系统语言是中文,但是写入进去中文字符串还是会转换成??,暂时不清楚是什么原因导致的。
我还碰到了一个问题,就是我给一个DOCX文档同时写入一个类模块和文档模块,就会导致文档损坏打不开,我单独写入一个类模块或者文档模块倒是正常打开,很奇怪,这是VBA的问题导致的还是Aspose写入导致的呢?

@wslioy 要在文档中使用 VBA,需要将文档保存为 DOCM 格式。 例如

Document doc = new Document();

VbaProject project = new VbaProject();
project.Name = "Aspose.Project";
doc.VbaProject = project;

VbaModule module = new VbaModule();
module.Name = "Aspose.Module";
module.Type = VbaModuleType.ProceduralModule;
module.SourceCode = "源代码";

doc.VbaProject.Modules.Add(module);

doc.Save("output.docm");

至于变成"??? "的中文字符,这是 MS Word 和 VBA 方面的问题,Aspose.Words 无法处理。

我的代码是这样的,调用了两个Application的事件,但是AutoOpen中的两个语句会导致文档损坏,直接闪退,如果我手动在新的文档编辑这个类和ThisDocument的AutoOpen方法,却是可以正常执行的,我很好奇为什么手动编辑和Aspose.words插入这两种方式会有这种区别,而且Aspose.words插入的宏代码不能二次编辑,会出现各种报错,这个也是MS Word 和 VBA 方面的问题吗?麻烦帮忙排查一下出现这种情况的原因

      // 创建文档
        Document doc = new Document(filePath);

        // 创建 VBA 项目
        VbaProject vbaProject = new VbaProject();
        vbaProject.setName("VBAProject");
        // 创建 ThisDocument 模块并设置事件代码
        VbaModule thisDocument = vbaProject.getModules().get("ThisDocument");
        String sourceCode =
                "Private Sub AutoOpen()\n" +
                "   Dim X As New ClassEventModule\n"+
                "   X.App = Application\n" +
                "End Sub\n";
        System.out.println(sourceCode);
        thisDocument.setSourceCode(sourceCode);
        // class
        VbaModule vbaClass = new VbaModule();
        vbaClass.setName("ClassEventModule");
        String classCode =
                "Public WithEvents App As Application\n" +
                "\n"+
                "private Sub App_DocumentBeforePrint(ByVal Doc As Document, Cancel As Boolean)\n" +
                "    If Doc.FullName = ThisDocument.FullName Then\n" +
                "        MsgBox \"Printing is not allowed!\", vbCritical, \"warning\"\n" +
                "        Cancel = True\n" +
                "    End If\n" +
                "End Sub\n" +
                "\n"+
                "private Sub App_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)\n" +
                "    If Doc.FullName = ThisDocument.FullName Then\n" +
                "        If SaveAsUI Then\n" +
                "            MsgBox \"Saving as is not allowed\", vbCritical, \"warning\"\n" +
                "            Cancel = True\n" +
                "        End If\n" +
                "    End If\n" +
                "End Sub\n";
        System.out.println(classCode);
        vbaClass.setType(VbaModuleType.CLASS_MODULE);
        vbaClass.setSourceCode(classCode);
        vbaProject.getModules().add(vbaClass);
        // 保存为 .docm 文件
        doc.setVbaProject(vbaProject);
        doc.save(outPath, SaveOptions.createSaveOptions(SaveFormat.DOCM));

@wslioy 感谢您报告此问题。 我们已经在我们的内部问题跟踪系统中打开了以下新工单,并将根据 免费支持政策 中提到的条款提供它们的修复:

Issue ID(s): WORDSNET-28291

如果您需要优先支持以及直接联系我们的付费支持管理团队,您可以获得 付费支持服务

@wslioy 在分析之后,我们可以为您提供解决方法。 请在 sorceCode 中添加 Attribute VB_Base = "1Normal.ThisDocument " (看起来实际值并不重要),并在 classCode 中添加 Attribute VB_Base = “0{FCFB3D2A-A0FA-1068-A738-08002B3371B6}” (看起来这里可以是任何 GUID)。

以下是运行良好的更新代码:

Document doc = new Document();
doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2019);

VbaProject vbaProject = new VbaProject();
vbaProject.setName("VBAProject");
doc.setVbaProject(vbaProject);

VbaModule thisDocument = vbaProject.getModules().get("ThisDocument");
String sourceCode =
        "Attribute VB_Base = \"1Normal.ThisDocument\"\n" +
        "\n" +
        "Private m_eventHandler As ClassEventModule\n" +
        "\n" +
        "Sub AutoOpen()\n" +
        "    Set m_eventHandler = New ClassEventModule\n" +
        "    Set m_eventHandler.App = Application\n" +
        "    MsgBox \"Event handlers registered\", vbInformation\n" +
        "End Sub";
thisDocument.setSourceCode(sourceCode);

VbaModule vbaClass = new VbaModule();
vbaClass.setName("ClassEventModule");
vbaClass.setType(VbaModuleType.CLASS_MODULE);
String classCode =
        "Attribute VB_Base = \"0{FCFB3D2A-A0FA-1068-A738-08002B3371B6}\"\n" +
        "\n" +
        "Public WithEvents App As Word.Application\n" +
        "\n" +
        "Private Sub App_DocumentBeforePrint(ByVal Doc As Word.Document, Cancel As Boolean)\n" +
        "    On Error Resume Next\n" +
        "    If Doc.Name = ThisDocument.Name Then\n" +
        "        MsgBox \"Printing is not allowed!\", vbCritical, \"Warning\"\n" +
        "        Cancel = True\n" +
        "    End If\n" +
        "End Sub\n" +
        "\n" +
        "Private Sub App_DocumentBeforeSave(ByVal Doc As Word.Document, SaveAsUI As Boolean, Cancel As Boolean)\n" +
        "    On Error Resume Next\n" +
        "    If Doc.Name = ThisDocument.Name Then\n" +
        "        If SaveAsUI Then\n" +
        "            MsgBox \"Saving as is not allowed\", vbCritical, \"Warning\"\n" +
        "            Cancel = True\n" +
        "        End If\n" +
        "    End If\n" +
        "End Sub";
vbaClass.setSourceCode(classCode);
vbaProject.getModules().add(vbaClass);

doc.save("output.docm");

非常感谢,这样可以正常的使用Application事件。

1 Like