unoserver
py3o
LibreOfficeによるPDF変換(エクスポート)
フィルターオプション
py3oconverter.jar
py3o.renderers.juno
に同梱されたJavaパッケージ
ソースコード
py3o.renderers.juno-0.8.2.dev1-py2-none-any.whl
に同梱されているpy3oconverter.jar
package py3oconverter;
import com.google.gson.Gson;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.comp.helper.Bootstrap;
import com.sun.star.connection.NoConnectException;
import com.sun.star.container.XIndexAccess;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XStorable;
import com.sun.star.io.ConnectException;
import com.sun.star.io.IOException;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.text.XDocumentIndex;
import com.sun.star.text.XDocumentIndexesSupplier;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uri.ExternalUriReferenceTranslator;
import com.sun.star.util.CloseVetoException;
import com.sun.star.util.XCloseable;
import com.sun.star.util.XRefreshable;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import java.util.Map;
/* loaded from: py3oconverter.jar:py3oconverter/Convertor.class */
public class Convertor {
private XComponentContext remoteContext = null;
private String serverHost;
private String serverPort;
public Convertor(String serverHost, String serverPort) {
this.serverHost = serverHost;
this.serverPort = serverPort;
}
public void convert(String inputFilePath, String outputFilePath, String filterName, String filterOptions, String filterData) throws ConnectException, Exception {
convertDocument(outputFilePath, filterName, openDocument(inputFilePath, connect(serverHost, serverPort)), filterOptions, filterData);
}
private String createUNOFileURL(String filePath) {
URL url = null;
try {
url = new File(filePath).toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
String internalURL = ExternalUriReferenceTranslator.create(remoteContext).translateToInternal(url.toExternalForm());
if (internalURL.length() == 0 && filePath.length() > 0) {
System.out.println("File URL conversion failed. File location contains illegal characters: " + filePath);
}
return internalURL;
}
protected void refreshDocument(XComponent document) {
XRefreshable refreshable = (XRefreshable) UnoRuntime.queryInterface(XRefreshable.class, document);
if (refreshable != null) {
refreshable.refresh();
}
}
protected void refreshIndexes(XComponent document) {
XDocumentIndexesSupplier indexesSupplier = (XDocumentIndexesSupplier) UnoRuntime.queryInterface(XDocumentIndexesSupplier.class, document);
if (indexesSupplier != null) {
XIndexAccess documentIndexes = indexesSupplier.getDocumentIndexes();
for (int i = 0; i < documentIndexes.getCount(); i++) {
try {
XDocumentIndex documentIndex = (XDocumentIndex) UnoRuntime.queryInterface(XDocumentIndex.class, documentIndexes.getByIndex(i));
if (documentIndex != null) {
documentIndex.update();
}
} catch (WrappedTargetException | IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
}
private void convertDocument(String outputFilePath, String filterName, XComponent document, String filterOptions, String filterData) {
XStorable storable = (XStorable) UnoRuntime.queryInterface(XStorable.class, document);
refreshDocument(document);
refreshIndexes(document);
PropertyValue[] storeProps = new PropertyValue[3];
storeProps[0] = new PropertyValue();
storeProps[0].Name = "Overwrite";
storeProps[0].Value = new Boolean(true);
storeProps[1] = new PropertyValue();
storeProps[1].Name = "FilterName";
storeProps[1].Value = filterName;
Map<String, String> optionsMap = new Gson().fromJson(filterOptions, Map.class);
Map<String, String> typesMap = new Gson().fromJson(filterData, Map.class);
PropertyValue[] filterDataProps = new PropertyValue[optionsMap.size()];
int i = 0;
for (Map.Entry<String, String> entry : optionsMap.entrySet()) {
String key = entry.getKey();
String type = typesMap.get(key);
String value = entry.getValue();
filterDataProps[i] = new PropertyValue();
filterDataProps[i].Name = key;
if ("boolean".equals(type)) {
filterDataProps[i].Value = Boolean.parseBoolean(value);
} else if ("integer".equals(type)) {
filterDataProps[i].Value = Integer.valueOf(Integer.parseInt(value));
} else if ("string".equals(type)) {
filterDataProps[i].Value = value;
}
i++;
}
storeProps[2] = new PropertyValue();
storeProps[2].Name = "FilterData";
storeProps[2].Value = filterDataProps;
try {
storable.storeToURL(createUNOFileURL(outputFilePath), storeProps);
XCloseable closeable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, storable);
if (closeable != null) {
try {
closeable.close(false);
} catch (CloseVetoException e) {
e.printStackTrace();
}
} else {
document.dispose();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private XComponent openDocument(String filePath, XDesktop desktop) {
XComponentLoader loader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktop);
PropertyValue[] loadProps = {new PropertyValue()};
loadProps[0].Name = "Hidden";
loadProps[0].Value = new Boolean(true);
XComponent document = null;
try {
document = loader.loadComponentFromURL(createUNOFileURL(filePath), "_blank", 0, loadProps);
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
private XDesktop connect(String host, String port) throws ConnectException, Exception {
try {
XComponentContext initialContext = Bootstrap.createInitialComponentContext((Hashtable) null);
remoteContext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, ((XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, ((XUnoUrlResolver) UnoRuntime.queryInterface(XUnoUrlResolver.class, initialContext.getServiceManager().createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", initialContext))).resolve("uno:socket,host=" + host + ",port=" + port + ";urp;StarOffice.ServiceManager"))).getPropertyValue("DefaultContext"));
return (XDesktop) UnoRuntime.queryInterface(XDesktop.class, remoteContext.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop", remoteContext));
} catch (NoConnectException e) {
throw new ConnectException("Connection failed for host: " + host + ", and port: " + port + " : " + e.getMessage());
} catch (Exception e) {
throw new Exception("Open office exception : " + e);
}
}
}
詳細
py3oconverter
パッケージの Convertor
クラスについて詳しく説明します。このクラスは、OpenOffice/LibreOffice を使用してドキュメントの変換を行うためのものです。
クラスの概要
Convertor クラスは、リモートコンテキストを使用してOpenOffice/LibreOfficeサーバーに接続し、ドキュメントを変換します。このクラスは、ODTファイルを別のフォーマットに変換するための各種メソッドを提供します。
主なメンバー変数
xRemoteContext
: リモートコンテキストを格納します。
server_host と server_port: OpenOffice/LibreOfficeサーバーのホスト名とポート番号を格納します。
主なメソッド
Convertor
コンストラクタ
public Convertor(String serverHost, String serverPort)
サーバーのホスト名とポート番号を設定します。
convert
メソッド
public void convert(String inputFilePath, String outputFilePath, String filterName, String filterOptions, String filterData) throws ConnectException, Exception
ドキュメントを指定されたフォーマットに変換します。
パラメータ:
inputFilePath
: 変換元ファイルのパス
outputFilePath
: 変換後のファイルのパス
filterName
: 変換に使用するフィルター名
filterOptions
: フィルターオプションのJSON文字列
filterData
: フィルターデータのJSON文字列
createUNOFileURL
メソッド
private String createUNOFileURL(String filePath)
ファイルパスを内部URLに変換します。
refreshDocument
メソッド
protected void refreshDocument(XComponent xComponent)
ドキュメントをリフレッシュします。
refreshIndexes
メソッド
protected void refreshIndexes(XComponent xComponent)
ドキュメントのインデックスを更新します。
convert_document
メソッド
private void convert_document(String outputFilePath, String filterName, XComponent xComponent, String filterOptions, String filterData)
ドキュメントの変換を実行します。
openDocument
メソッド
private XComponent openDocument(String filePath, XDesktop xDesktop)
ドキュメントを開きます。
connect
メソッド
private XDesktop connect(String serverHost, String serverPort) throws ConnectException, Exception
OpenOffice/LibreOfficeサーバーに接続します。
メソッドの階層構造
これらのメソッドを使用して、OpenOffice/LibreOfficeを利用したドキュメント変換を実現します。例えば、ODTファイルをPDFに変換するなどの用途に利用できます。
Convertor
├── Convertor(String serverHost, String serverPort)
└── convert(String inputFilePath, String outputFilePath, String filterName, String filterOptions, String filterData)
├── connect(String serverHost, String serverPort)
│ └── XComponentContext initialContext
│ └── XUnoUrlResolver resolve
│ └── XDesktop getServiceManager
├── openDocument(String filePath, XDesktop desktop)
│ └── createUNOFileURL(String filePath)
│ └── URL toExternalForm
└── convertDocument(String outputFilePath, String filterName, XComponent document, String filterOptions, String filterData)
├── refreshDocument(XComponent document)
│ └── XRefreshable refresh
├── refreshIndexes(XComponent document)
│ └── XDocumentIndexesSupplier getDocumentIndexes
└── storeToURL(String createUNOFileURL, PropertyValue[] storeProps)
└── XCloseable close
pythonからの呼び出し
py3o.renderers.juno
は py3oconverter パッケージを使用して、OpenOffice/LibreOffice サーバー経由でドキュメントの変換を自動化することができます。。以下に各部分の説明を階層化して示します。
モジュールのインポート
import jpype
from jpype import startJVM
from jpype import JPackage
import os
import json
import platform
import logging
import pkg_resources
jpype: Java仮想マシン (JVM) とPython間の相互運用をサポートするライブラリ。
os, json, platform, logging, pkg_resources: 標準ライブラリと追加パッケージ。
ハードコードされたJARリソースの定義
ureitems = [
"juh.jar",
"jurt.jar",
"ridl.jar",
"unoloader.jar",
"java_uno.jar",
"gson.jar",
]
basisitems = ["unoil.jar"]
get_oo_context
関数
def get_oo_context():
...
return context
プラットフォームに応じて、Javaクラスパスのセパレータやサブパスを設定します。
start_jvm
関数
def start_jvm(jvm, oobase, urebase, max_mem):
...
startJVM(jvm_abs, java_classpath, java_maxmem)
JVMを開始し、指定されたクラスパスとメモリ設定を適用します。
Convertor
クラス
class Convertor(object):
...
def convert(self, infilename, outfilename, filtername, pdf_options):
...
__init__
メソッド
def __init__(self, host, port):
...
jconvertor_package = JPackage('py3oconverter').Convertor
self.jconvertor = jconvertor_package(host, port)
OpenOfficeサーバーのホストとポートを初期化し、Java側の Convertor クラスを使用します。
convert
メソッド
def convert(self, infilename, outfilename, filtername, pdf_options):
...
self.jconvertor.convert(
infilename,
outfilename,
filtername,
pdf_options_json,
pdf_options_types_json)
入力ファイルを指定されたフィルターで変換し、出力ファイルに保存します。