在 libreoffice 文档中枚举 FieldMarks
Enumerate FieldMarks in a libreoffice document
Libreoffice 将 docx 文本字段表示为字段标记。
我可以使用以下 MWE 通过 UNO 桥创建它们:
# to connect as client`
import uno
from pythonscript import ScriptContext
resolver = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.bridge.UnoUrlResolver')
# start libreoffice as
# libreoffice --writer --accept="socket,host=localhost,port=2002;urp;"`
client = resolver.resolve('uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
XSCRIPTCONTEXT = ScriptContext(client, None, None)
doc = XSCRIPTCONTEXT.getDocument()
def cursor():
return doc.getCurrentController().getSelection().getByIndex(0)
t = doc.getText()
# insert text before field
t.insertString(cursor(), 'Fieldmark-Start|', False)
# create the field
field = doc.createInstance('com.sun.star.text.Fieldmark')
fieldcursor = cursor()
# add the String 'Field contents' to the document
fieldcursor.setString('Field contents')
# actually insert the field in the document (linked to the string)
field.attach(fieldcursor)
field.setFieldType('Testfieldtype')
field.setName('Fieldname')
# insert text after the field
t.insertString(cursor(), '|Fieldmark-End', False)
保存后段落正确保存为
<text:p text:style-name="Standard">Fieldmark-Start|
<field:fieldmark-start text:name="Fieldname" field:type="Testfieldtype"/>
Field contents
<field:fieldmark-end/>
|Fieldmark-End</text:p>
但是,我在文档中找不到任何现有的字段标记:
# check if the contents are there
doc.getText().getString()
# -> 'Fieldmark-Start|Field contents|Fieldmark-End'
# try to enumerate all fields
tf = doc.getTextFields()
tf.hasElements() # -> true
enum = tf.createEnumeration()
enum.hasMoreElements() # -> false
# field = enum.nextElement()
# -> com.sun.star.container.NoSuchElementException
即使它们没有出现在 doc.getTextFields()
或 doc.getBookmarks()
中,仍然可以通过枚举文本找到它们。
paragraphs = t.createEnumeration()
while paragraphs.hasMoreElements():
text_portions = paragraphs.nextElement().createEnumeration()
while text_portions.hasMoreElements():
text_portion = text_portions.nextElement()
if text_portion.TextPortionType == "TextFieldStart":
bookmark = text_portion.Bookmark
bookmark.Name
bookmark.FieldType
结果:
'Fieldname'
'Testfieldtype'
从这里开始,关注UNO API 文档如https://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Bookmarks.
在 https://ask.libreoffice.org/en/question/30175/how-access-fieldmarks-with-api/ 上提出了同样的问题,但没有有效的答案。
Libreoffice 将 docx 文本字段表示为字段标记。
我可以使用以下 MWE 通过 UNO 桥创建它们:
# to connect as client`
import uno
from pythonscript import ScriptContext
resolver = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.bridge.UnoUrlResolver')
# start libreoffice as
# libreoffice --writer --accept="socket,host=localhost,port=2002;urp;"`
client = resolver.resolve('uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
XSCRIPTCONTEXT = ScriptContext(client, None, None)
doc = XSCRIPTCONTEXT.getDocument()
def cursor():
return doc.getCurrentController().getSelection().getByIndex(0)
t = doc.getText()
# insert text before field
t.insertString(cursor(), 'Fieldmark-Start|', False)
# create the field
field = doc.createInstance('com.sun.star.text.Fieldmark')
fieldcursor = cursor()
# add the String 'Field contents' to the document
fieldcursor.setString('Field contents')
# actually insert the field in the document (linked to the string)
field.attach(fieldcursor)
field.setFieldType('Testfieldtype')
field.setName('Fieldname')
# insert text after the field
t.insertString(cursor(), '|Fieldmark-End', False)
保存后段落正确保存为
<text:p text:style-name="Standard">Fieldmark-Start|
<field:fieldmark-start text:name="Fieldname" field:type="Testfieldtype"/>
Field contents
<field:fieldmark-end/>
|Fieldmark-End</text:p>
但是,我在文档中找不到任何现有的字段标记:
# check if the contents are there
doc.getText().getString()
# -> 'Fieldmark-Start|Field contents|Fieldmark-End'
# try to enumerate all fields
tf = doc.getTextFields()
tf.hasElements() # -> true
enum = tf.createEnumeration()
enum.hasMoreElements() # -> false
# field = enum.nextElement()
# -> com.sun.star.container.NoSuchElementException
即使它们没有出现在 doc.getTextFields()
或 doc.getBookmarks()
中,仍然可以通过枚举文本找到它们。
paragraphs = t.createEnumeration()
while paragraphs.hasMoreElements():
text_portions = paragraphs.nextElement().createEnumeration()
while text_portions.hasMoreElements():
text_portion = text_portions.nextElement()
if text_portion.TextPortionType == "TextFieldStart":
bookmark = text_portion.Bookmark
bookmark.Name
bookmark.FieldType
结果:
'Fieldname'
'Testfieldtype'
从这里开始,关注UNO API 文档如https://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Bookmarks.
在 https://ask.libreoffice.org/en/question/30175/how-access-fieldmarks-with-api/ 上提出了同样的问题,但没有有效的答案。