欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何将SAP Document Builder的word控件设置成只读模式 crmabaperpC4CSAP成都研究院 

程序员文章站 2022-07-14 08:17:04
...

Recently I am working on a customer project and one customer requirement is they do not want to the word document be editable in the word control. That means all buttons and menus in toolbar should be disabled.

 

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院 

 

The first idea comes to my mind is the flag “enableReadWrite“.

 

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院 

 

As documented in sap help,it can fulfill my help but unfortunately it is deprecated. Regardless of this warning I have a try and found it does not work indeed.

 

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院 

 

Then I am speculating that if the document uploaded is read only, it is for sure that the toolbar will be disabled. So the issue turns to that how could I mark the document to be read only on the fly during uploading.

Since word 2007 the format of MS office follows the so called “Open office” protocol whose specification could be found here. If you change the file type extension from .docx to .zip and open it with WinRAR, you will find the document is actually a bundle of several single files ( called document part in SAP internal ). The editability is controlled within the file settings.xml.

 

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院 

 

If you don’t know the exact syntax, just google it. I use the explanation from this one in google:

Now the task is quite easy, just add the necessary xml tag into the document source code. You do not need to manually parse the document source code since SAP has already done this job. You can just reuse standard class CL_DOCX_DOCUMENT. Since I need to insert the document protection node in “settings” node, a simple transformation is written for this. The magic is between line 18 and 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>

and find a proper place to call the 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 ).

after that the tag will be there in settings.xml:

 

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院 

 

The word control before upload document looks like below, buttons and menus available:

 

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院 

 

After upload, menu and button are disabled. If you try to edit the document, there will be notifications in the right pane to give you a hint that is not possible.

 

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院 

 

Of course this solution does not work for lower version of MS word like word2003. Fortunately my customer has enough money and they are already using Office 2013 so I do not need to worry about it.

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

如何将SAP Document Builder的word控件设置成只读模式
            
    
    
        crmabaperpC4CSAP成都研究院