- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想要完成的事情:
问题:
我可以使用非 CTL 语言(例如英语)执行此操作:
from docx import Document
from docx.enum.style import WD_STYLE_TYPE
from docx.shared import Pt
user_font_name = 'FreeMono'
user_font_size = 14
doc = Document()
my_style = doc.styles.add_style('style_name',WD_STYLE_TYPE.PARAGRAPH)
my_font = my_style.font
my_font.name = user_font_name
my_font.size = Pt(user_font_size)
p = doc.add_paragraph('some text',my_style)
# persian_p = doc.add_paragraph('نوشته',my_style)
# FreeMono supports Persian language so the problem is not the font
doc.save('file.docx')
但是,如果我将文本更改为波斯文本,其字体不会更改为指定的字体。
为什么会这样:
我怎么知道的:
附加信息:
最佳答案
在查看 docx 文件数小时后,我惊恐地意识到,答案就在文档的 style.xml 文件中。这是为有类似问题的人修复它的一种方法:
文本方向问题:
字体变化问题的xml解释:
默认样式已更改的文档在其 style.xml 文件中显示了一些不同的内容。在 "w:rPr"下的普通段落样式中,您可以看到有一个额外的 "w:szCs"确定复杂脚本字体的大小(您不能通过更改 style.font.size 来更改)和在 "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)
关于带有 CTL(复杂文本布局)语言的 python-docx add_style,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45627652/
我之前发布过question已得到答复,但我也需要对此进行查询。我有一个包含这样数据的表结构(日期格式为 dd/mm/yyyy)。 ID Account Number Unit Ad
我正在使用 React Native Calendars 并尝试为议程组件构建我的数据。 预期的数据结构是(一个对象) { '2012-05-22': [{text: 'item 1 - any j
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
两列城镇和优先级。 我需要对表进行排序,以便优先级=1的城镇排在第一位,并且不按名称 ASC 排序,而其余城镇则按名称 ASC 排序。 我该怎么做? 谢谢;) 更新 SELECT * FROM map
我有三个表“Hardware_model”、“Warehouse”和“Brand”,并且表以这种方式一起引用:Hardware_model 仓库Hardware_model 品牌 现在我要执行以下
我有一个 MySQL 表 (tbl_filters),包含 3 列:id、cat、val id 和 val 是数字,cat 是 varchar。每个 id 有多行。 我还有另一个包含多个列的表 (tb
我想获取字段的不同值,比方说:field1...这需要一个如下查询:“从表中选择不同的(字段1)” 但是,对于某些记录,field1 为空,并且还有另一列可以替代 field1,即 field2。对于
表 1 - 用户 id username items 1 Paul 1(0020);2(0001); 表 2 - 项目 id name 1 name_here 在我的用户的项目中,我输入了 2(000
我想连接同一个表 4 次以获取列的显示方式,我不确定是否可以在 1 个 SQL 语句中完成。 tbl_用户名 id username 1 Adam 2 Bob 3 Chris tbl_机
首先,我刚刚开始自己学习JS,没有任何编程经验,这意味着我仍然要了解这种出色的编程语言的基本构建模块。 我的问题与我编写的以下代码有关: let orderCount = 0; con
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve t
我正在使用 XMAPP,MySQL 正在正常运行。在 phpMyAdmin 中,我不太明白这一点,所以我尝试在 PHP 中创建一个。使用此代码,它会告诉我数据库 benutzer。尽管我在 phpMy
是否有一种高效的算法可以找到平均度最大的子图(可能是图本身)? 最佳答案 The paper "Finding a Maximum-Density Subgraph" by Andrew Goldbe
目录 1、业务背景 2、场景分析 3、流程设计 1、业务流程 2、导入流程
我有 2 个表: 1) 包含自 1900 年 1 月 1 日以来所有日期的 Masterdates 表 2) Stockdata 表,其中包含表单中的股票数据 日期、交易品种、开盘价、最高价、最低价、
我有一个非常复杂的 UI,其状态栏不断变化,其中包含多种类型的状态消息,并且 UI 具有复杂的图表控件和已加载的指示性地理 map 。 现在这些小而复杂的区域的数据上下文具有同样复杂的 ViewMod
有人可以用简单的方式向我解释为什么常量在大 O 表示法中无关紧要吗?为什么添加常量时复杂性保持不变。这不是作业问题,我只是想更好地理解这一点。让我明白这个大 O 是为了看到一个函数在接近无穷大时的行为
我在 flex 搜索索引中有以下文档。 [{ "_index": "ten2", "_type": "documents", "_id": "c323c
我有一个以零碎的方式构建的 LINQ 查询,如下所示: var initialQuery = from item in MyContext where xxx == yyy select item;
我目前正在涉足 SQL,并且希望针对我所创建的问题获得一些帮助。 为了练习一些编程,我正在制作一个 IOU 应用程序。下面是我存储的表我的借条记录(忽略一些相关栏目)。该表允许用户说“嘿,你欠我 X
我是一名优秀的程序员,十分优秀!