使用 ABAP 代码将 Word 文档设置成只读

举报
汪子熙 发表于 2024/03/01 19:30:49 2024/03/01
【摘要】 我在从事 SAP document builder 开发时,曾经遇到一个客户需求,将 word control 里的 word 文档,设置成 read-only,也就是说,浏览器里 word 界面的工具栏上的所有按钮,状态应该设置为 disabled实现这个需求的关键在于这个叫做 enableReadWrite 的 checkbox:如果上传的文档是只读的,那么工具栏肯定会被禁用。所以这个需...

我在从事 SAP document builder 开发时,曾经遇到一个客户需求,将 word control 里的 word 文档,设置成 read-only,也就是说,浏览器里 word 界面的工具栏上的所有按钮,状态应该设置为 disabled

实现这个需求的关键在于这个叫做 enableReadWrite 的 checkbox:

如果上传的文档是只读的,那么工具栏肯定会被禁用。所以这个需求就变成了,如何在上传过程中将文档标记为只读。

自 Word 2007 起,MS Office 的格式遵循所谓的 open office 协议。Open Office 协议指的是一系列开放办公室软件领域的协议和标准,这些协议和标准的制定旨在促进不同办公软件之间的互操作性和数据交换。这样的努力旨在打破不同厂商之间的软件壁垒,使用户能够在不同的办公软件中无缝地共享和编辑文档、电子表格、演示文稿等办公文件。

Open Office 协议通常关注文件格式和数据交换的规范,以确保各种办公软件之间能够正确理解和处理文件。

从 Word 2013 开始,微软的 Word 文档也加入了 Open Office 的大家庭。

如果将文件类型扩展名从.docx更改为.zip并用WinRAR打开它,会发现该文档实际上是多个单个文件的捆绑包(SAP内部称为文档部分)。

可编辑性在文件 settings.xml 中控制。

现在任务非常简单,只需将必要的 xml 标签添加到文档源代码中即可。

不需要手动解析文档源代码,因为 SAP 已经完成了这项工作。

可以重复使用标准类 CL_DOCX_DOCUMENT。
由于我需要在 settings 节点中插入文档保护节点,因此为此编写了一个简单的转换。

问题的突破口在于第 18 行和第 21 行之间。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14" version="1.0">
  <xsl:output encoding="UTF-8" indent="no" method="xml" omit-xml-declaration="no" version="1.0"/>
  <!-- Match everything all nodes and attributes -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="w:settings">
    <xsl:element name="w:settings">
      <xsl:for-each select="@*">
        <xsl:copy/>
      </xsl:for-each>
      <xsl:element name="w:documentProtection">
        <xsl:attribute name="w:edit">readOnly</xsl:attribute>
        <xsl:attribute name="w:enforcement">1</xsl:attribute>
      </xsl:element>
      <xsl:copy-of select="./*"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

寻找一个合适的地方来调用 ABAP transformation:

 DATA: lr_element   TYPE REF TO if_wd_context_element,
         lv_file_data TYPE xstring,
         lv_ret       TYPE i,
         lx_temp      TYPE xstring,
         lv_msg       TYPE string,
         lt_parms     TYPE /ipro/tt_key_value_pair,
         ls_parm      LIKE LINE OF lt_parms.
   lr_element = me->wd_context->get_element( ).
   CHECK lr_element IS NOT INITIAL.
   lr_element->get_attribute( EXPORTING name = 'BINARY' IMPORTING value = lv_file_data ).
   DATA(lo_docx) = cl_docx_document=>load_document( lv_file_data  ).
   DATA(lo_main_part) = lo_docx->get_maindocumentpart( ).
   DATA(lo_docx_settings) = lo_main_part->get_documentsettingspart( ).
   DATA(lx_settings) = lo_docx_settings->get_data( ).
   /ipro/cl_docx_utilities=>transform( EXPORTING  iv_input_xstring    = lx_settings
                                   iv_transform_name  = '/IPRO/DOCXCC_PROTECT'
                                   it_parameters      = lt_parms
                        IMPORTING  ev_result          = lx_temp
                                   ev_ret             = lv_ret
                                   ev_message         = lv_msg  ).
   lo_docx_settings->feed_data( lx_temp ).
   DATA(lx_docx_package) = lo_docx->get_package_data( ).
   lr_element->set_attribute( EXPORTING name = 'BINARY'  value = lx_docx_package ).

上面的代码执行完毕之后,就能在 settings.xml 里看见 flag 了:

下面是实现好的效果。在 word 文档上传之前,word control 里工具栏所有的按钮,都是可用状态:

上传之后,我们之前介绍的 ABAP 代码生效了,文档变为了 readonly 状态:

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。