被保护的文档设置仅标签内容可编辑,清空标签内容会删除文档标签的问题

我需要设置一个word文件中仅标签内容可编辑,我使用了 protect 方法进行文档保护,并使用 EditableRangeStart 设置标签内容为可编辑区域。保存文件设置后,我在本地进行文件编辑,当我准备把标签内容全删除再填写新的内容后,该位置定义的文档标签被删除了。

这是我的代码:

public static void main(String[] args) {
    try {
        // 加载要进行编辑限制的文档
        Document doc = new Document("E:/test.docx");
        doc.protect(ProtectionType.READ_ONLY, "123456");

        DocumentBuilder builder = new DocumentBuilder(doc);
        BookmarkCollection bookmarks = doc.getRange().getBookmarks();
        for (int i = 0; i < bookmarks.getCount(); i++) {
            Bookmark bookmark = bookmarks.get(i);
            builder.moveToBookmark(bookmark.getName(), true, true);
            EditableRangeStart innerEditableRangeStart = builder.startEditableRange();
            builder.moveToBookmark(bookmark.getName(), false, false);
            builder.endEditableRange(innerEditableRangeStart);
        }

        // 保存保护后的文档
        doc.save("E:/test1.docx");
    } catch (Exception e) {
        log.info("处理异常:", e);
    }
}

源文件:
test.docx (13.9 KB)

生成的文件内容:

先删除标签的内容:

填写新的内容:

此时,文档标签 bookmark1 已被删除。

@whitemeen 它看起来像是 MS Word 中的一个错误。 Aspose.Words 正确地在书签内插入可编辑范围。 但 MS Word 由于某种原因在编辑后删除了可编辑范围之外的书签:

作为解决方法,您可以分别在书签开始和可编辑范围开始之间以及可编辑范围结束和书签结束之间放置隐藏的空格。 例如看下面的代码:

Document doc = new Document("C:\\Temp\\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
doc.protect(ProtectionType.READ_ONLY, "123456");

for (Bookmark bookmark : doc.getRange().getBookmarks())
{
    builder.moveToBookmark(bookmark.getName(), true, true);
    builder.getFont().setHidden(true);
    builder.write(" ");
    builder.getFont().setHidden(false);
    EditableRangeStart innerEditableRangeStart = builder.startEditableRange();
    builder.moveToBookmark(bookmark.getName(), false, false);
    builder.endEditableRange(innerEditableRangeStart);
    builder.getFont().setHidden(true);
    builder.write(" ");
    builder.getFont().setHidden(false);
}

doc.save("C:\\Temp\\out.docx");

上面的代码中使用的 builder.getFont().setHidden(true),我发现并没有隐藏文字的效果,仅是使用了“…”作为下画线,请问有其他方案吗,我使用的是 Apose 16.4.0。

image.jpg (118.8 KB)

@whitemeen 这是预料之中的行为。MS Word 用"…"高亮显示隐藏文本,这是因为 MS Word 设置中启用了该显示选项。如果不想显示隐藏文本,可以在文件 > 选项 > 显示中禁用该选项。

请问,对文档中早已存在的多个可编辑区域,我怎么才能获取到它们引用并进行可编辑限制的删除呢?

这是我的原始文件:

test.docx (13.9 KB)

我将它从系统中下载时经过如下代码的处理:

public static void main(String[] args) {
    try {
        // 加载要进行编辑限制的文档
        Document doc = new Document("E:/test.docx");

        doc.protect(ProtectionType.READ_ONLY, "123456");

        DocumentBuilder builder = new DocumentBuilder(doc);
        BookmarkCollection bookmarks = doc.getRange().getBookmarks();
        for (int i = 0; i < bookmarks.getCount(); i++) {
            Bookmark bookmark = bookmarks.get(i);
            builder.moveToBookmark(bookmark.getName(), true, true);
            builder.getFont().setHidden(true);
            builder.write(" ");
            builder.getFont().setHidden(true);
            EditableRangeStart innerEditableRangeStart = builder.startEditableRange();
            builder.moveToBookmark(bookmark.getName(), false, false);
            builder.endEditableRange(innerEditableRangeStart);
            builder.getFont().setHidden(true);
            builder.write(" ");
            builder.getFont().setHidden(true);
        }

        doc.getCustomDocumentProperties().add("file_id", "123456789");
        doc.getLayoutOptions().isShowHiddenText(true);
        // 保存保护后的文档
        doc.save("E:/test-download.docx");
    } catch (Exception e) {
        log.info("处理异常:", e);
    }
}

得到了 READ_ONLY 的文档,并且给文档里所有书签都设置了可编辑的处理:

test-download.docx (11.3 KB)

现在我进行文档编辑后,需要将该文档上传到系统中,我尝试这样处理:

public static void main(String[] args) {
    try {
        Document doc = new Document("E:/test-download.docx");
        DocumentProperty fileId = doc.getCustomDocumentProperties().get("file_id");
        System.out.println("fileId: " + fileId);
        DocumentBuilder builder = new DocumentBuilder(doc);
        BookmarkCollection bookmarks = doc.getRange().getBookmarks();
        for (int i = 0; i < bookmarks.getCount(); i++) {
            Bookmark bookmark = bookmarks.get(i);
            builder.moveToBookmark(bookmark.getName(), true, true);
            Node currentNode = builder.getCurrentNode();
            currentNode.remove();
            builder.moveToBookmark(bookmark.getName(), false, false);
            Node currentNode1 = builder.getCurrentNode();
            Node previousSibling = currentNode1.getPreviousSibling();
            previousSibling.remove();
        }
        doc.protect(ProtectionType.NO_PROTECTION, "123456");
        // 保存保护后的文档
        doc.save("E:/test-upload.docx");
   } catch (Exception e) {
        log.info("处理异常:", e);
   }
}

但是上传的文件保留着可编辑区域的红色标识,我需要怎么才能清除它们?

image.png (14.2 KB)

@whitemeen 在这种情况下,您只需删除所有可编辑的范围,而无需访问书签:

Document doc = new Document("input.docx");
doc.unprotect("123456");
DocumentProperty fileId = doc.getCustomDocumentProperties().get("file_id");
System.out.println("fileId: " + fileId);
for (EditableRangeStart editableRangeStart : (Iterable<EditableRangeStart>) doc.getChildNodes(NodeType.EDITABLE_RANGE_START, true))
{
    EditableRange editableRange = editableRangeStart.getEditableRange();
    editableRange.remove();
}

doc.save("output.docx");

如果要删除所有书签,可以使用

doc.getRange().getBookmarks().clear();

如果要删除书签的内容,请按以下方法操作:

Document doc = new Document("input.docx");
doc.unprotect("123456");
DocumentProperty fileId = doc.getCustomDocumentProperties().get("file_id");
System.out.println("fileId: " + fileId);
DocumentBuilder builder = new DocumentBuilder(doc);
for (Bookmark bookmark : doc.getRange().getBookmarks()) {
    builder.moveToBookmark(bookmark.getName());
    Node startNode = builder.getCurrentNode();
    Node currentNode = startNode.nextPreOrder(doc);
    currentNode.remove();
}

doc.save("output.docx");

可以通过代码关闭 word 的“高亮显示隐藏文本”设置吗,我尝试使用 doc.getLayoutOptions().isShowHiddenText(false); 但是不可行。

@whitemeen Aspose.Words 无法在 MS Word 中更改此选项。doc.getLayoutOptions().isShowHiddenText(false); 用于转换为 PDF 等固定页面格式。