ですその答えは文書のstyle.xmlファイルで嘘でした。文字方向と
問題:
- あなたはアラビア語やペルシャ語で入力した場合は、テキストを右に揃えることがわかるかもしれませんここで同様の問題を持つ人々のためにそれを修正する方法のようなものですあなたの問題をすべて解決するわけではありません。テキストの方向を変更しないと、カーソルと句読点は画面の右端に残ります(最後の文字の後には表示されません)。必要に応じて右揃えもありません。これでdocument.xmlの "textDirection"値を 'lrTb'(Left-Right/Top-Bottom)から 'rlTb'に変更してもpython-docxのテキスト方向を変更できないため、LibreOfficeデフォルトの段落スタイル( 'Normal')を私が心に留めていたもの(rtlテキスト方向など)に変更します。これは、実際にはPythonで行う必要がないので、後で多くの時間を節約します。フォント変更、問題の
のXml説明:
は、変更されたデフォルトのスタイルを持つ文書は、そのstyle.xmlファイルに異なる物事のカップルを示しています。 "w:rPr"の下にある標準段落スタイルでは、複雑なスクリプトフォントのサイズ(style.font.sizeを変更することで変更できない)を決定する追加の "w:szCs" w:rFonts "" cs "の値が指定されたペルシャ語フォントになりました。また、 "w:lang"という値 "bidi"は、 "fa-IR"(ペルシア語用)です。ここで私が話しているXML部分です:
<w:rPr>
<w:rFonts w:ascii="FreeMono" w:hAnsi="FreeMono" w:cs="FreeFarsi"/>
<w:sz w:val="40"/>
<w:rtl/>
<w:cs/>
<w:szCs w:val="40"/>
<w:lang w:val="en-Us" w:bidi="fa-IR"/>
</w:rPr>
今style.font.sizeを変更するだけで、「SZ」の値(西部のフォントサイズ)を変更し、「szCs」値(Csに何もしません。フォントサイズ)。同様にstyle.font.nameは "w:rFonts"の "ascii"と "hAnsi"値だけを変更し、 "cs"値には何もしません。したがって、これらの値を変更するには、私のスタイル要素をPythonで変更する必要がありました。
ソリューション:
from docx import Document
from docx.shared import Pt
#path to doc with altered style:
base_doc_location = 'base.docx'
doc = Document(base_doc_location)
my_style = doc.styles['Normal']
# define your desired fonts
user_cs_font_size = 16
user_cs_font_name = 'FreeFarsi'
user_en_font_size = 12
user_en_font_name = 'FreeMono'
# get <w:rPr> element of this style
rpr = my_style.element.rPr
#==================================================
'''This probably isn't necessary if you already
have a document with altered style, but just to be
safe I'm going to add this here'''
if rpr.rFonts is None:
rpr._add_rFonts()
if rpr.sz is None:
rpr._add_sz()
#==================================================
'''Get the nsmap string for rpr. This is that "w:"
at the start of elements and element values in xml.
Like these:
<w:rPr>
<w:rFonts>
w:val
The nsmap is like a url:
http://schemas.openxmlformats.org/...
Now w:rPr translates to:
{nsmap url string}rPr
So I made the w_nsmap string like this:'''
w_nsmap = '{'+rpr.nsmap['w']+'}'
#==================================================
'''Because I didn't find any better ways to get an
element based on its tag here's a not so great way
of getting it:
'''
szCs = None
lang = None
for element in rpr:
if element.tag == w_nsmap + 'szCs':
szCs = element
elif element.tag == w_nsmap + 'lang':
lang = element
'''if there is a szCs and lang element in your style
those variables will be assigned to it, and if not
we make those elements and add them to rpr'''
if szCs is None:
szCs = rpr.makeelement(w_nsmap+'szCs',nsmap=rpr.nsmap)
if lang is None:
lang = rpr.makeelement(w_nsmap+'lang',nsmap =rpr.nsmap)
rpr.append(szCs)
rpr.append(lang)
#==================================================
'''Now to set our desired values to these elements
we have to get attrib dictionary of these elements
and set the name of value as key and our value as
value for that dict'''
szCs_attrib = szCs.attrib
lang_attrib = lang.attrib
rFonts_atr = rpr.rFonts.attrib
'''sz and szCs values are string values and 2 times
the font size so if you want font size to be 11 you
have to set sz (for western fonts) or szCs (for CTL
fonts) to "22" '''
szCs_attrib[w_nsmap+'val'] =str(int(user_cs_font_size*2))
'''Now to change cs font and bidi lang values'''
rFonts_atr[w_nsmap+'cs'] = user_cs_font_name
lang_attrib[w_nsmap+'bidi'] = 'fa-IR' # For Persian
#==================================================
'''Because we changed default style we don't even
need to set style every time we add a new paragraph
And if you change font name or size the normal way
it won't change these cs values so you can have a
font for CTL language and a different font for
western language
'''
persian_p = doc.add_paragraph('نوشته')
en_font = my_style.font
en_font.name = user_en_font_name
en_font.size = Pt(user_en_font_size)
english_p = doc.add_paragraph('some text')
doc.save('ex.docx')
編集(コードの改善):
私はいくつかの改善を使用し、それらの下に、より良いラインを入れることができます行をコメントしました。
#rpr = my_style.element.rPr # If None it'll throw errors later
rpr = my_style.element.get_or_add_rPr() # this avoids potential errors
#if rpr.rFonts is None:
# rpr._add_rFonts()
rFonts = rpr.get_or_add_rFonts()
#if rpr.sz is None:
# rpr._add_sz()
rpr.get_or_add_sz()
#by importing these you can make elements and set values quicker
from docx.oxml.shared import OxmlElement, qn
#szCs = rpr.makeelement(w_nsmap+'szCs',nsmap=rpr.nsmap)
szCs = OxmlElement('w:szCs')
#lang = rpr.makeelement(w_nsmap+'lang',nsmap =rpr.nsmap)
lang = OxmlElement('w:lang')
#szCs_attrib = szCs.attrib
#lang_attrib = lang.attrib
#rFonts_atr = rpr.rFonts.attrib
#szCs_attrib[w_nsmap+'val'] =str(int(user_cs_font_size*2))
#rFonts_atr[w_nsmap+'cs'] = user_cs_font_name
#lang_attrib[w_nsmap+'bidi'] = 'fa-IR'
szCs.set(qn('w:val'),str(int(user_cs_font_size*2)))
lang.set(qn('w:bidi'),'fa-IR')
rFonts.set(qn('w:cs'),user_cs_font_name)