0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【py3o】py3oconverter (Javaパッケージ:odt等をpdfに変換)

Posted at

unoserver

py3o

LibreOfficeによるPDF変換(エクスポート)

フィルターオプション

py3oconverter.jar

py3o.renderers.junoに同梱されたJavaパッケージ

ソースコード

py3o.renderers.juno-0.8.2.dev1-py2-none-any.whlに同梱されているpy3oconverter.jar

py3oconverter
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)

入力ファイルを指定されたフィルターで変換し、出力ファイルに保存します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?