如何使用OpenXML创建从右到左的TOC

时间:2021-07-03 20:27:07

I have created a TOC for my DOCX file using C# and OpenXML using this tutorial. The problem is I cannot manage list of my TOC to get right-to-left. I was able to change to change sample XML to make TOC's header RtL. But it seems nothing can change the list items. Here is the changed XML I'm using:

我使用本教程使用C#和OpenXML为我的DOCX文件创建了一个TOC。问题是我无法管理我的TOC列表从右到左。我能够更改为更改示例XML以生成TOC的标头RtL。但似乎没有什么可以改变列表项。这是我正在使用的更改的XML:

<w:sdt xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>

  <w:sdtPr>
    <w:pPr>
      <w:jc w:val='right'/>
    </w:pPr>
    <w:rPr>
      <w:rFonts w:asciiTheme='minorHAnsi' w:eastAsiaTheme='minorHAnsi' w:hAnsiTheme='minorHAnsi'/>
      <w:bCs w:val='0'/>
      <w:i w:val='0'/>
      <w:color w:val='auto'/>
      <w:sz w:val='22'/>
      <w:szCs w:val='22'/>
      <w:rtl/>
      <w:lang w:eastAsia='en-US' w:bidi='fa-IR'/>
    </w:rPr>
    <w:docPartObj>
      <w:docPartGallery w:val='Table of Contents'/>
      <w:docPartUnique/>
    </w:docPartObj>
  </w:sdtPr>

  <w:sdtEndPr>
    <w:pPr>
      <w:jc w:val='right'/>
    </w:pPr>
    <w:rPr>
      <w:rFonts w:asciiTheme='minorHAnsi' w:cstheme='minorBidi' w:eastAsiaTheme='minorHAnsi' w:hAnsiTheme='minorHAnsi'/>
      <w:color w:val='auto'/>
      <w:sz w:val='22'/>
      <w:szCs w:val='22'/>
      <w:rFonts w:cstheme='minorBidi'/>
      <w:rtl w:val='1'/>
      <w:lang w:bidi='fa-IR'/>
    </w:rPr>
  </w:sdtEndPr>

  <w:sdtContent>

    <w:p>
      <w:pPr>
        <w:spacing w:line='50' w:lineRule='auto'/>
        <w:jc w:val='right'/>
      </w:pPr>
      <w:r>
        <w:rPr>
          <w:rtl w:val='1'/>
          <w:lang w:eastAsia='en-US' w:bidi='fa-IR'/>
        </w:rPr>
        <w:t>
          <!-- empty parag -->
        </w:t>
      </w:r>
    </w:p>

    <w:p>
      <w:pPr>
        <w:pStyle w:val='TOCHeading'/>
        <w:spacing w:line='500' w:lineRule='auto'/>
        <w:jc w:val='right'/>
      </w:pPr>
      <w:r>
        <w:rPr>
          <w:rtl w:val='1'/>
          <w:lang w:bidi='fa-IR'/>
        </w:rPr>
        <w:t>{0}</w:t>
      </w:r>
    </w:p>

    <w:p>
      <w:pPr>
        <w:pStyle w:val='TOC1'/>
        <w:jc w:val='right' />
        <w:rPr>
          <w:rFonts w:eastAsiaTheme='minorEastAsia' w:cstheme='minorBidi' w:hint='cs'/>
          <w:noProof/>
          <w:lang w:bidi='fa-IR'/>
          <w:rtl w:val='1'/>
        </w:rPr>
        <w:tabs>
          <w:tab w:val='left' w:leader='dot' w:pos='{1}'/>
        </w:tabs>
      </w:pPr>

      <w:jc w:val='right' />
      <w:lang w:bidi='fa-IR' />

      <w:r>
        <w:rPr>
          <w:rFonts w:ascii='Lucida Console'/>
          <w:i/>
          <w:sz w:val='24'/>
          <w:rtl w:val='1'/>
          <w:lang w:bidi='fa-IR'/>
        </w:rPr>
        <w:fldChar w:fldCharType='begin'/>
      </w:r>
      <w:r>
        <w:rPr>
          <w:rFonts w:ascii='Lucida Console'/>
          <w:i/>
          <w:sz w:val='24'/>
          <w:rtl w:val='1'/>
          <w:lang w:bidi='fa-IR'/>
        </w:rPr>
        <w:instrText xml:space='preserve'> {2} </w:instrText>
      </w:r>
      <w:r>
        <w:rPr>
          <w:rFonts w:ascii='Lucida Console'/>
          <w:i/>
          <w:sz w:val='24'/>
          <w:rtl w:val='1'/>
          <w:lang w:bidi='fa-IR'/>
        </w:rPr>
        <w:fldChar w:fldCharType='separate'/>
      </w:r>

    </w:p>

    <w:p>

      <w:pPr>
        <w:jc w:val='right' />
        <w:rPr>
          <w:lang w:bidi='fa-IR'/>
          <w:rtl w:val='1'/>
        </w:rPr>
      </w:pPr>

      <w:jc w:val='right' />
      <w:lang w:bidi='fa-IR' />

      <w:r>
        <w:rPr>
          <w:b/>
          <w:bCs/>
          <w:noProof/>
          <w:rFonts w:ascii='Lucida Console'/>
          <w:i/>
          <w:sz w:val='24'/>
          <w:rtl w:val='1'/>
          <w:lang w:bidi='fa-IR'/>
        </w:rPr>
        <w:fldChar w:fldCharType='end'/>
      </w:r>
    </w:p>
  </w:sdtContent>
</w:sdt>

I almost tried every property on every node! But nothing changed. Do you have any idea how to do that? Thanks in advance.

我几乎尝试了每个节点上的每个属性!但没有改变。你知道怎么做吗?提前致谢。

2 个解决方案

#1


0  

Maybe remove spaces and return in your file with regex? I tested with small piece of your xml.

也许删除空格并使用正则表达式在文件中返回?我测试了一小块你的xml。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<w:sdt xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>\n" +
                  "<w:sdtPr>\n" +
                    "<w:pPr>\n" +
                      "<w:jc w:val='right'/>\n" +
                    "</w:pPr>\n" +
                    "<w:rPr>\n" +
                      "<w:rFonts w:asciiTheme='minorHAnsi' w:eastAsiaTheme='minorHAnsi' w:hAnsiTheme='minorHAnsi'/>\n" +
                      "<w:bCs w:val='0'/>\n" +
                      "<w:i w:val='0'/>\n" +
                      "<w:color w:val='auto'/>\n";

            //remove spaces at beginning of line
            string pattern1 = @"^\s+<";
            input = Regex.Replace(input, pattern1, "<");
            //remove spaces and return at end of line
            string pattern2 = ">\\s*\n";
            input = Regex.Replace(input, pattern2, ">",RegexOptions.Singleline);

        }
    }
}
​

#2


0  

the trick is to use "Bidi" inside your paragraph (such a cute name). If you manually create a word with a "right to left" TOC and look at a differences inside the xml you'll notice only one tag is added

诀窍是在你的段落中使用“Bidi”(这么可爱的名字)。如果您手动创建一个带有“从右到左”TOC的单词并查看xml内部的差异,您会发现只添加了一个标记

<w:p w:rsidP="00A63AAE" w:rsidRDefault="00A63AAE" w:rsidR="000E5A53">
  <w:pPr>
    <w:pStyle w:val="TM2"/>
    <w:bidi/>

So, on each paragraphProperties of your TOC, do a pPr.Append(new BiDi()) and it should do the work.

所以,在你的TOC的每个段落属性上,做一个pPr.Append(新的BiDi()),它应该做的工作。

To have access to bidirection in Word, you have to add a Language (like Arabic) that use bidirection. Maybe you'll have to add a language like this in your word to enable the use of Bidi (there is a chance word delete bidi tag after a save if it don't find a bidirectional language in the word setting)

要在Word中访问双向,您必须添加使用双向的语言(如阿拉伯语)。也许你必须在你的单词中添加这样的语言才能使用Bidi(如果在单词设置中没有找到双向语言,则在保存后有可能删除bidi标签)

#1


0  

Maybe remove spaces and return in your file with regex? I tested with small piece of your xml.

也许删除空格并使用正则表达式在文件中返回?我测试了一小块你的xml。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<w:sdt xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>\n" +
                  "<w:sdtPr>\n" +
                    "<w:pPr>\n" +
                      "<w:jc w:val='right'/>\n" +
                    "</w:pPr>\n" +
                    "<w:rPr>\n" +
                      "<w:rFonts w:asciiTheme='minorHAnsi' w:eastAsiaTheme='minorHAnsi' w:hAnsiTheme='minorHAnsi'/>\n" +
                      "<w:bCs w:val='0'/>\n" +
                      "<w:i w:val='0'/>\n" +
                      "<w:color w:val='auto'/>\n";

            //remove spaces at beginning of line
            string pattern1 = @"^\s+<";
            input = Regex.Replace(input, pattern1, "<");
            //remove spaces and return at end of line
            string pattern2 = ">\\s*\n";
            input = Regex.Replace(input, pattern2, ">",RegexOptions.Singleline);

        }
    }
}
​

#2


0  

the trick is to use "Bidi" inside your paragraph (such a cute name). If you manually create a word with a "right to left" TOC and look at a differences inside the xml you'll notice only one tag is added

诀窍是在你的段落中使用“Bidi”(这么可爱的名字)。如果您手动创建一个带有“从右到左”TOC的单词并查看xml内部的差异,您会发现只添加了一个标记

<w:p w:rsidP="00A63AAE" w:rsidRDefault="00A63AAE" w:rsidR="000E5A53">
  <w:pPr>
    <w:pStyle w:val="TM2"/>
    <w:bidi/>

So, on each paragraphProperties of your TOC, do a pPr.Append(new BiDi()) and it should do the work.

所以,在你的TOC的每个段落属性上,做一个pPr.Append(新的BiDi()),它应该做的工作。

To have access to bidirection in Word, you have to add a Language (like Arabic) that use bidirection. Maybe you'll have to add a language like this in your word to enable the use of Bidi (there is a chance word delete bidi tag after a save if it don't find a bidirectional language in the word setting)

要在Word中访问双向,您必须添加使用双向的语言(如阿拉伯语)。也许你必须在你的单词中添加这样的语言才能使用Bidi(如果在单词设置中没有找到双向语言,则在保存后有可能删除bidi标签)