Python Tech xlwings

Python xlwingsを使った印刷範囲設定・プリンタ印刷・PDF変換の方法(複数Excel一括印刷も)

外部ライブラリ xlwings を使うと、PythonからExcelを操作できるプログラムを簡単に作成することができます。

Excelファイルの印刷を自動化する方法にはVBAマクロを実装するものもありますが、Pythonでも同じことを実現可能です。

  • 印刷(プリンター)の実行
  • PDFに変換
  • 印刷範囲の調整

高機能なPythonのファイル抽出機能と組み合わせると、条件にあったExcelファイルを自動で編集、範囲を設定して印刷する流れを自動化できます。

ページの最後では、特定のファイル名のExcelを自動で一括印刷するコードを例示しています。ぜひ参考にしてみてください。

 

結論

印刷の実行(ネイティブAPI利用)

sheet.api.PrintOut(From=1, To=1, Copies=1, ActivePrinter='NATIVE PRINTER NAME')

 

PDFに変換

ワークブック全体のPDFを生成

wb.to_pdf()

 

シート単位でPDFを生成

sheet.to_pdf()

 

印刷範囲の設定

sheet.page_setup.print_area = '$A$2:$H$40'

 

印刷範囲のクリア

sheet.page_setup.print_area = None

 

実行環境

Microsoft Office Excel 2019

> python --version
Python 3.9.4

> pip freeze
xlwings==0.24.9

 

今回使用したサンプルデータ

総務省 人口推計 各月1日現在人口 (年齢、男女別人口)
統計局ホームページ/人口推計

 

印刷(プリンター)の実行

現在のところ xlwings のPython APIにはプリンター印刷機能がありません。

そこで、Excelインスタンスに直接アクセスするオブジェクトを取得して(VBAと同じように)印刷を実行します。

xlwings は本質的にはpywin32のプロセス間通信のラッパーなので、sheet.api でExcelのオブジェクトを取得できます。

印刷を行うのは Sheet.PrintOut() メソッドです。

PrintOut(From, To, Copies, Preview, ActivePrinter,...)

From印刷を開始するページの番号。None(デフォルト)なら最初のページから印刷
To印刷を終了するページの番号。None(デフォルト)なら最後のページまで印刷
Copies印刷部数。 None(デフォルト)なら1 部。
PreviewTrue ときは印刷プレビューを表示
ActivePrinterプリンター名を指定。プリンター一覧に表示されている名前でOK

その他のパラメータはドキュメント参照。
Workbook.PrintOut メソッド (Excel) | Microsoft Docs

wb: Book = xw.books.open('./data/population.xlsx')
sheet: Sheet = wb.sheets[0]
sheet.api.PrintOut(From=1, To=1, Copies=1, ActivePrinter='Canon XX9999')

 

注意ポイント

xlwings はあらかじめExcelを起動しておく必要があります。空のワークブックを新規作成するなどしてから実行してください。

 

PDFに変換

ExcelシートをPDFとして出力する機能はPython APIで提供されており、簡単に実装可能。xlwings バージョン 0.22.3から追加された機能です。

PDF変換を行うには Book.to_pdf() または Sheet.to_pdf() を呼び出します

 

ブック単位で印刷する場合

Book.to_pdf(path=None, include=None, exclude=None, exclude_start_string='#', show=False)

pathPDFファイルのパス。Noneの場合はブックと同じ名前で同じディレクトリに保存される
include変換に含めるシートを指定。シート番号(1から始まる)またはシート名のリストで指定
exclude変換から除くシートを指定。シート番号(1から始まる)またはシート名のリストで指定
exclude_start_string除外するシートの接頭辞を文字列で指定(この文字列から始まる名前を持つシートは変換対象外となる)
show作成後にPDFビューアで開くならTrueを渡す

 

シート単位で印刷する場合

Sheet.to_pdf(path=None, show=False)

pathPDFファイルの保存パス。Noneの場合はシートと同じ名前で同じディレクトリに保存される
show作成後にPDFビューアで開くならTrueを渡す

標準機能で使用できるパラメータのみ。より詳しくはドキュメント参照。
Python API - xlwings Documentation

 

# ワークブック全体、複数シートを指定してPDFを生成
wb.to_pdf(show=True)

# シート単位でPDFを生成
sheet.to_pdf(show=True)

 

印刷範囲の設定

xlwings.main.PageSetup クラスのインスタンス(Book.PageSetupからアクセス)が持つ print_area メンバにセル範囲を設定するだけです。

ここでは統計局の人口統計(2021年9月)をサンプルとして設定してみます。

 

サンプルファイルに既に設定されている印刷範囲を取得します。

p_area = sheet.page_setup.print_area
print(p_area)
# $A$1:$M$56

 

この印刷範囲で印刷(PDF変換)した結果

印刷範囲を改めて設定します。

sheet.page_setup.print_area = '$A$4:$F$34'
sheet.to_pdf(path='population_details.pdf', show=True)

 

この印刷範囲で印刷(PDF変換)した結果

 

印刷範囲のクリア

同様にNoneを設定すると、印刷範囲をクリアできます。

sheet.page_setup.print_area = None

 

実際に印刷(PDF変換)すると印刷範囲がクリアされていることが確認できます。

 

複数のExcelブックの印刷範囲を設定して印刷

上述の方法を活用し複数Excelブックを連続印刷するサンプルコードを作成してみます。

まずは、特定のディレクトリ(フォルダ)にある、特定の名前を持つExcelファイルを抽出します。

ファイル名による抽出には標準パッケージの glob を使用します。この例では名前が 05k2- から始まる、拡張子 .xlsx のファイルをリストで取得します。

# 特定のファイル名を持つExcelを取得
import glob
work_dir = './data/population'
files_target = glob.glob(f'{work_dir}/05k2-*.xlsx')
print(files_target)
# ['./data/population\\05k2-1_202101.xlsx', './data/population\\05k2-1_202102.xlsx', './data/population\\05k2-1_202103.xlsx', './data/population\\05k2-1_202104.xlsx', './data/population\\05k2-1_202105.xlsx', './data/population\\05k2-1_202106.xlsx', './data/population\\05k2-1_202107.xlsx', './data/population\\05k2-1_202108.xlsx', './data/population\\05k2-1_202109.xlsx']

 

for構文のループを使って、先ほど取得したファイルリスト files_target の全ファイルを印刷します。

なお、xw.books.open(path_to_file) で正しくファイルパスを認識させるために、Windowsでは バックスラッシュ \ を スラッシュ/に置換しています。

印刷前には印刷範囲の設定も行っています。PageSetup.print_area パラメータにセル範囲を渡して設定できます。

forループの中では、最後に必ずBook.close()を読んでワークブックを閉じます(印刷が終わってもExcelブックが開いたまま蓄積されてしまうため)。

import os
# ファイルごとに印刷範囲設定、印刷
for fp in files_target:
    # (Windowsのみ)ファイルパスの修正
    fp = fp.replace('\\', '/')

    # (解説用)現在処理しているファイル名
    fname = os.path.basename(fp)
    print(f"処理中: {fname}")

    wb: Book = xw.books.open(fp)
    sheet: Sheet = wb.sheets[0]
    sheet.page_setup.print_area = '$A$4:$F$34'

    # 印刷する場合
    # sheet.api.PrintOut(From=1, To=1, Copies=1, ActivePrinter='Canon ZZ9999 series')

    # PDF変換する場合
    sheet.to_pdf(path=f'{work_dir}/{fname}', show=False)

    wb.close()

 

さらにカスタマイズする方法

サンプルコードでは印刷するExcelファイル名、印刷範囲を決め打ちで指定していますが、関数化したり起動時パラメータで指定できるようにすると、作業ごとに柔軟に変更できるでしょう。

また、今回は印刷範囲は固定で指定しています。ですがxlwingsには強力なrange範囲の拡張機能が備わっているので、ファイルごと(またはテーブルごとに)印刷範囲を柔軟に変えることも可能です。Rangeの詳しい使用方法はドキュメントを参照

 

今回参考にしたページ・資料

Python API - xlwings Documentation

Workbook.PrintOut メソッド (Excel) | Microsoft Docs

xlwingsで印刷範囲を設定する - Nochi Log

  • この記事を書いた人

次世代ペンギン

長いのでペンギンとお呼びください。システム開発・プログラミングのお仕事をしています。甘味とコーヒーは生命線。多くの人に役立つ情報のシェアが目標です。

人気の記事

1

会社員でプログラマーとして働いている人、インフラやネットワークのエンジニアとして働いている人の中には、フリーランスのプログラマーとして独立、もしくは転向したい人もいるので ...

2

キャリアアップのため、または高収入を目指して、しっかりプログラミングを学びたいという人が増えてきましたね。 この記事では現役のエンジニアである私が、実際に仕事で稼げるよう ...

3

フリーランスのプログラマーにとって収入の向上に最も直結するのはスキルです。 必要なスキル、スキルの獲得方法が気になる人も多いでしょう。 また、これからフリーランスを目指す ...

4

Vuetifyの v-progress-circular コンポーネントは、数値データや処理状況を環状(円状)のデザインで教えてくれるUIデザインです。 ローディングのス ...

5

Vuexのstore(ストア)を使うと、各コンポーネント間で個別にデータのやり取りすることなく、データを一元的に管理できます。Vueでは欠かせない機能といえるでしょう。 ...

-Python, Tech, xlwings
-, , , ,

© 2021 ペンギンのーと