LibreOffice/OpenOffice 能否以编程方式向现有的 .docx/.xlsx/.pptx 文件添加密码?

Posted

技术标签:

【中文标题】LibreOffice/OpenOffice 能否以编程方式向现有的 .docx/.xlsx/.pptx 文件添加密码?【英文标题】:Can LibreOffice/OpenOffice programmatically add passwords to existing .docx/.xlsx/.pptx files? 【发布时间】:2019-07-15 17:10:22 【问题描述】:

TL;DR 版本 - 我需要使用 LibreOffice 以编程方式向 .docx/.xlsx/.pptx 文件添加密码,但它不起作用,也没有错误报告,我添加密码的请求很简单忽略,并保存同一文件的无密码版本。

深入: 我正在尝试使用 LibreOffice 编写密码保护现有 .docx/.xlsx/.pptx 文件的脚本。 我在 Windows 8.1 64 位专业版上使用 64 位 LibreOffice 6.2.5.2,这是撰写本文时的最新版本。 虽然我可以通过 UI 手动执行此操作 - 具体而言,我打开“普通”文档,执行“另存为”,然后勾选“使用密码保存”,并在其中输入密码,但我无法通过任何方式使其工作的自动化。我一直在尝试通过 Python/Uno,但没有任何收获。尽管下面的代码正确打开并保存了文档,但我添加密码的尝试被完全忽略了。奇怪的是,当我这样做时,文件大小从 12kb 缩小到了 9kb。

这是我的代码:

import socket
import uno
import sys
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)

from com.sun.star.beans import PropertyValue
properties=[]

oDocB = desktop.loadComponentFromURL ("file:///C:/Docs/PlainDoc.docx","_blank",0, tuple(properties) )

sp=[]
sp1=PropertyValue()
sp1.Name='FilterName'
sp1.Value='MS Word 2007 XML'
sp.append(sp1)
sp2=PropertyValue()
sp2.Name='Password'
sp2.Value='secret'
sp.append(sp2)

oDocB.storeToURL("file:///C:/Docs/PasswordDoc.docx",sp)
oDocB.dispose()

我使用 Python/Uno 打开受密码保护的文件取得了很好的效果,但我无法使用它来保护以前未受保护的文档。我尝试启用宏记录器并记录我的操作 - 它记录了以下 LibreOffice BASIC 代码:

sub SaveDoc
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(2) as new com.sun.star.beans.PropertyValue
args1(0).Name = "URL"
args1(0).Value = "file:///C:/Docs/PasswordDoc.docx"
args1(1).Name = "FilterName"
args1(1).Value = "MS Word 2007 XML"
args1(2).Name = "EncryptionData"
args1(2).Value = Array(Array("OOXPassword","secret"))

dispatcher.executeDispatch(document, ".uno:SaveAs", "", 0, args1())


end sub

即使我尝试运行它,它...保存一个不受保护的文档,没有密码加密。我什至尝试将上面的宏转换为等效的 Python 代码,但也无济于事。我没有收到任何错误,它根本不保护文档。

最后,出于绝望,我什至尝试了不包括 LibreOffice 的其他方法,例如,根据以下现有 *** 问题使用 Apache POI 库:

Python or LibreOffice Save xlsx file encrypted with password

...但我只是收到一条错误消息“错误:无法找到或加载主类 org.python.util.jython”。我已经尝试升级我的 JDK,调整示例中使用的路径,即有一个“智能”,但仍然没有乐趣。我怀疑上面的错误很容易修复,但我不是 Java 开发人员,缺乏这方面的经验。

有人有解决办法吗?您是否有一些可以执行此操作的 LibreOffice 代码(密码保护 .docx/.xlsx/.pptx 文件)?或者 OpenOffice,我并不在乎我使用哪个包。或者完全是别的东西!

注意:我很欣赏这使用全脂 Microsoft Office 是微不足道的,但由于 Microsoft 的许可限制,这个项目完全不可行 - 我必须使用替代方案。

【问题讨论】:

关于 BASIC 代码,最好避免使用 UNO 调度调用。 wiki.openoffice.org/wiki/… 【参考方案1】:

以下示例来自有用的宏信息的第 40 页(文件第 56 页) 对于 Andrew Pitonyak (http://www.pitonyak.org/AndrewMacro.odt) 的 OpenOffice.org。该文档指向 OpenOffice.org Basic,但通常也适用于 LibreOffice。该示例与宏记录器版本的不同之处主要在于它使用了记录在案的 API,而不是调度调用。

5.8.3。使用密码保存文档

要使用密码保存文档,您必须设置“密码” 属性。

清单 5.19: 使用密码保存文档。

Sub SaveDocumentWithPassword
  Dim args(0) As New com.sun.star.beans.PropertyValue
  Dim sURL$

  args(0).Name  ="Password"
  args(0).Value = "test"

  sURL=ConvertToURL("/andrew0/home/andy/test.odt")
  ThisComponent.storeToURL(sURL, args()) 
End Sub

参数名称区分大小写,因此“密码”不起作用。

【讨论】:

以上是关于LibreOffice/OpenOffice 能否以编程方式向现有的 .docx/.xlsx/.pptx 文件添加密码?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 LibreOffice/OpenOffice/Excel 公式中减去时间常数?

从 JAVA 使用 LibreOffice/OpenOffice 转换文件格式

Excel、Libreoffice/Openoffice Calc:计算“正确”答案

如何使用 C# 和 LibreOffice/OpenOffice 在电子表格单元格中设置粗体文本?

基本操作系统 - LibreOffice/OpenOffice 冲突,Dpkg 错误(未满足的依赖项) - 陷入循环

LibreOffice Calc / OpenOffice Calc / Excel:如何显示负持续时间?