LibreOffice Calc で使う Excel Like UNO を仮リリース

正月にちまちま整備していた Excel Like Uno が、まあ動くようになったので仮リリースしておきます。

https://github.com/moonmile/ExcelLikeUno

moonmile/ExcelLikeUno: LibreOffice の Python マクロを Excel VBA ライクに操作 github.com/moonmile/Exc…一旦、仮リリース。

Tomoaki Masuda (@moonmile.bsky.social) 2026-01-05T03:04:00.398Z

12月に LibreOffice Calce の Python マクロを使って、諸々を試していたのですが、現状の uno api だけでは限界がありそうなので、更にラップをするライブラリを作って試しています。

目的としては、

  • UNO API の複雑さを隠蔽し、Excel/VBA に近いメソッド・プロパティ名でする
  • 型定義を充実させ、IDE 補完と静的解析をサポート

なところで、従来の Excel VBA に似せています。

実は LibreOffice Calc でも Option VBASupport 1 のオプションを付けると VBA 互換モードで動かせます。かなり Excel VBA に近いところまでエミュレートするので Excel VBA から移行する場合はこっちのほうが楽かもしれません。
ただ、いまさら VBA でやりたくないし、どうせならば Python か何か別の言語でやりたいところです。

サンプル calc_sample_cell.py

from excellikeuno import connect_calc
from excellikeuno.typing.calc import CellHoriJustify, CellVertJustify

(desktop, doc, sheet) = connect_calc() 
cell = sheet.cell(0, 0)  # A1 セルを取得
cell.text = "Hello, World!"  # 値を設定
sheet.range("A1:C1").merge(True)  # A1:C1 を結合

cell.font_size = 16
cell.font_name = "Arial"
cell.font_color = 0xFF0000  # フォント色を赤に

cell.row_height = 2000  # 行の高さを設定 20 mm
cell.HoriJustify = CellHoriJustify.CENTER
cell.VertJustify = CellVertJustify.CENTER


sheet.cell(0,1).text = "id"
sheet.cell(1,1).text = "name"
sheet.cell(2,1).text = "address"
sheet.range("A2:C2").CellBackColor = 0xFFBF00  # A2:C2 の背景色を設定

data = [
    [1, "masuda", "tokyo"],
    [2, "suzuki", "osaka"],
    [3, "takahashi", "nagoya"],
]
sheet.range("A3:C5").value = data  # 範囲にデータを一括設定

こんな感じで、最初に connect_calc() で接続してから、

  • sheet.cell( column, row ) でセルを取得
  • cell.font_size などのプロパティを使う

といいうことができます。テキストや値は、getText() や setText() を使うのではなく、text プロパティを使います。実際には、数値は value プロパティ、テキストが text プロパティにしてあります。

この Python コードを実行すると、LibreOffice Calc だと、こんな表示になります。
まあ、一般的な表ぐらいはできそうな状態です。

サンプル calc_sample_shogiban.py

罫線のサンプルを見てみましょう。

# 将棋盤を作る
from excellikeuno import connect_calc
from excellikeuno.typing.calc import CellHoriJustify, CellVertJustify
from excellikeuno.typing.structs import BorderLine

(desktop, doc, sheet) = connect_calc()
# sheet.name = "将棋盤"
ban = sheet.range("A1:I9");
ban.CellBackColor = 0xFFFACD  # 背景色を薄い黄色に設定
ban.row_height = 1000  # 行の高さを設定 20 mm
ban.column_width = 1000  # 列の幅を設定 20 mm
# 罫線を設定
for cell in [c for row in ban.cells for c in row]:
    borderline = BorderLine()
    borderline.Color = 0x000000
    borderline.OuterLineWidth = 50
    borderline.InnerLineWidth = 0
    borderline.LineDistance = 0

    cell.TopBorder = borderline
    cell.BottomBorder = borderline
    cell.LeftBorder = borderline
    cell.RightBorder = borderline
    # センタリング
    cell.HoriJustify = CellHoriJustify.CENTER
    cell.VertJustify = CellVertJustify.CENTER
    # フォントサイズを大きく
    cell.font_size = 16.0
    cell.CharColor = 0x000000  # 黒色に設定
    

# 駒を配置
pieces = [
    ["香", "桂", "銀", "金", "王", "金", "銀", "桂", "香"],
    ["", "飛", "", "", "", "", "", "角", ""],
    ["歩", "歩", "歩", "歩", "歩", "歩", "歩", "歩", "歩"],
    ["", "", "", "", "", "", "", "", ""],
    ["", "", "", "", "", "", "", "", ""],
    ["", "", "", "", "", "", "", "", ""],
    ["歩", "歩", "歩", "歩", "歩", "歩", "歩", "歩", "歩"],
    ["", "角", "", "", "", "", "", "飛", ""],
    ["香", "桂", "銀", "金", "王", "金", "銀", "桂", "香"],
]
ban.value = pieces  # 一括で駒を配置
# 相手の駒を反転表示
for r in range(9):
    for c in range(9):
        cell = ban.cell(c, r)
        if pieces[r][c] != "" and r < 3:
            cell.CharRotation = 180  # 180度回転

セルの大きさを変えて(いわゆる将棋盤にします)、駒をセルに書いていきます。
罫線をつけるところと、文字が180度回転させることができます。

まあ、これを Excel でやるかどうかは別ですが、Excel 方眼紙ぐらいならば作れそうです。

サンプル calc_sample_tsurukame.py

これは図形を配置する例です。

# 鶴亀オセロのサンプル
from excellikeuno import connect_calc
from excellikeuno.typing.structs import BorderLine

(desktop, doc, sheet) = connect_calc()
# sheet.name = "鶴亀オセロ"
ban = sheet.range("A1:H8");
ban.CellBackColor = 0x006400  # 背景色を濃い緑色に
ban.row_height = 1000  # 行の高さを設定 10 mm
ban.column_width = 1000  # 列の幅を設定 10 mm
# 罫線を設定
for cell in [c for row in ban.cells for c in row]:
    borderline = BorderLine()
    borderline.Color = 0x000000
    borderline.OuterLineWidth = 50
    borderline.InnerLineWidth = 0
    borderline.LineDistance = 0
    cell.TopBorder = cell.BottomBorder = cell.LeftBorder = cell.RightBorder = borderline

# オセロの駒を Shape で配置
pieces = [
    ["", "", "", "", "", "", "", ""],
    ["", "", "", "", "", "", "", ""],
    ["", "", "", "", "", "", "", ""],
    ["", "", "", "黒", "白", "", "", ""],
    ["", "", "", "白", "黒", "", "", ""],
    ["", "", "", "", "", "", "", ""],
    ["", "", "", "", "", "", "", ""],
    ["", "", "", "", "", "", "", ""],
]

for r in range(8):
    for c in range(8):
        cell = ban.cell(c, r)
        piece = pieces[r][c]
        if piece == "":
            continue
        sheet.shapes.add_ellipse_shape(
            x=cell.position.X + 200,
            y=cell.position.Y + 200,
            width=600,
            height=600,
            fill_color=0x000000 if piece == "黒" else 0xFFFFFF,
            line_color=0x000000,
        )

セルに罫線と背景色をつけて、オセロの駒は EllipseShape(楕円)を使います。

サンプル calc_sample_mahjong.py

フォント指定と TextShape を使った例です。

# 麻雀牌を並べる
from excellikeuno import connect_calc
from excellikeuno.typing.calc import LineStyle

(desktop, doc, sheet) = connect_calc()
# sheet.name = "麻雀牌"

hai = ['1','1','1', '2','2','2', '3','3','3', '4','4','4', 'a',' ','a']

# 13個の TextShape をシートに追加
for i in range(hai.__len__()):
    shape = sheet.shapes.add_text_shape(
        x=i * 1600,
        y=1000,
        width=1500,
        height=2000,
        text=str(hai[i]),
        fill_color=0xFFFFE0  # 薄い黄色
    )
    # 背景色を設定
    shape.FillColor = 0xFFFFE0  # 薄い黄色
    # 枠線の色を設定
    shape.LineStyle = LineStyle.SOLID  # SOLID
    shape.LineWidth = 50  # 線の太さを50 (1/100 mm)
    shape.LineColor = 0x008000  # 緑
    # テキストを中央揃え
    shape.HoriJustify = 1  # CENTER
    shape.VertJustify = 1  # CENTER
    # フォントサイズを大きく
    shape.font_size = 48.0
    # フォントの指定
    shape.CharFontName = "GL-MahjongTile"

# 麻雀牌を並べる
for i, shape in enumerate(sheet.shapes):
    shape.PositionX = i * 1600  # X位置をずらす
    shape.PositionY = 1000  # Y位置を10 mmに設定

# 完成

麻雀用のフォント “GL-MahjongTile” を使って TextShape を使った例です。
フォント自体は PC にインストールしないと駄目なので、埋め込みはできません。

図形が貼り付けられると、フローチャートとかネットワーク図とかの生成ができるようになります。

Calc 内部からマクロで呼び出す

いままでの例は外部から Python コードを使って呼び出すのですが、Calc 内部から Python コードを呼び出すには、XSCRIPTCONTEXT を使わないといけません。ただし、ちょっと初期化コードが外部呼出しからとは異なるのがややこしいのですが、以下のように書けます。

import inspect
import os
import sys
from typing import Any, Tuple

# Ensure this script's directory is importable so the local excellike package resolves
BASE_DIR = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
if BASE_DIR not in sys.path:
    sys.path.append(BASE_DIR)

from excellikeuno.table.sheet import Sheet 

# XSCRIPTCONTEXT に接続する
def connect_calc_script() -> Tuple[Any, Any, Sheet]:
    desktop = XSCRIPTCONTEXT.getDesktop()
    doc = desktop.getCurrentComponent()
    controller = doc.getCurrentController()
    sheet = Sheet(controller.getActiveSheet())
    return desktop, doc, sheet

def hello_to_cell():
    ( _, _, sheet ) = connect_calc_script()
    sheet.cell(0, 0).text = "Hello Excel Like for Python!"
    sheet.cell(0, 1).text = "こんにちは、Excel Like for Python!"
    sheet.cell(0,0).column_width = 10000  # 幅を設定

    cell = sheet.cell(0,1)
    cell.CellBackColor = 0x006400  # 濃い緑に設定
    cell.CharColor = 0xFFFFFF  # 文字色を白に設定

g_exportedScripts = (
    hello_to_cell,
)

こんな風にマクロを実行します。

connect_calc_script 部分を自前で書かないといけないのが難点なので、これは connect_calc にうまく吸収させる予定です。Calc と接続した後は、uno api は共通化されているので同じコードが動きます。つまり ExcelLikeUno ライブラリも外部からでも内部からもで動くということです。

内部で使える Python マクロで何が良くなるかと言うと、こんな風に vscode 使って Python コードが書けるという点です。Excel VBA 互換や、独自 Basic のコードだと付属のエディタでしか書けませんが、Python コードならば vscode で書けます。さらに言えば、git と連携もできるので、コードの保存が可能です。

ただし、コード保存の場所が

C:\Users\<ユーザー名>\AppData\Roaming\LibreOffice\4\user\Scripts\python\

というややこしい場所になっているのが難点で、excellikeuno ライブラリもここに配置しなければいけません。これも今後なんとかしていこうと考えています。

参照先

https://github.com/moonmile/ExcelLikeUno

README.md にもう少し詳しい説明があります。Linux 版や Docker 版などは、準備中。

カテゴリー: 開発, LibreOffice パーマリンク