我有一个相当大的DOCX文档集合,我需要删除除第一页以外的所有文档。据我所知,docx-python不支持这一点,因为它没有页面的概念。我考虑过的一种选择是转换为PDF,删除页面,然后再转换回DOCX,但我担心这会在某种程度上破坏格式,更不用说对于这么多文档可能会很慢。我最好的选择是什么?
类似:
for page in pages[1:]:
del page
您不能单独在数据级别删除DOCX文件中的特定页面,因为您甚至不能可靠地在数据级别引用页面。
你必须改变你的访问模型,不再依赖于分页,或者利用Word Automation的许可和服务器操作限制来破解一个解决方案。转向非基于页面的参考模型(例如基于段落或节的模型)是最好的选择。无论如何,这样的模型与现代内容管理需求更兼容,可以跨各种显示尺寸的设备。
在libreoffice论坛成员的帮助下,我有了一个解决方案:一个宏。这是相对缓慢的,但就是这样。请注意,这会删除所有非第一页,但您可以通过一些工作重写此操作以选择特定的页面或一系列页面。
注意:给未来读者的警告:如果这种近似对你有用,那就太好了,但你应该意识到,并不能保证LIbreOffice的分页算法与Microsoft Word的匹配,所以使用Word的用户可能会看到不同的删除。因此,您可能不希望在生产管道中使用它,并且对于一次性,您最好使用Word Automation来获得更接近大多数用户所看到的"页面"的结果。底线:任何设计依赖于DOCX "页面"仅在文档数据级别上存在本质缺陷。- - - - - -用户@kjhughes
宏观:
Dim doc, cursor
Dim props2(0) As New com.sun.star.beans.PropertyValue
Dim props(0) As New com.sun.star.beans.PropertyValue
props(0).Name="Hidden"
props(0).Value=True
For i = start To end_-1
doc = StarDesktop.LoadComponentFromUrl("file:///path_to_your_document_folder/" + subdir + "/doc" + i + ".docx", "_default", 0, props)
cursor = doc.CurrentController.getViewCursor()
cursor.gotoStart(false)
If cursor.jumpToNextPage() Then
cursor.gotoEnd(true)
cursor.setString("")
End If
doc.store(props1)
doc.close(true)
Next i
End Sub
office命令通过python:
clip_cmd = 'soffice --nologo --nofirststartwizard --norestore'
f' "macro:///Standard.Module1.del(0, 1000, <subdir_name>)"'
a = time.time()
print(f"clipping subdir <subdir_name>.")
sp.call(clip_cmd, shell=True, stdout=null)
print(f"This batch took {time.time() - a} seconds.")
当然,确保del
宏保存到你的libreoffice用户。