Calc(92)シート印刷時に改ページを挿入する位置をコントロールする

2018-12-08

旧ブログ

t f B! P L
シートを印刷時に結合セルの真ん中に改ページがくるとセルの内容が分割されて印刷されてしまうので、改ページをコントロール必要が生じました。「結合セルで改ページしない」というオプションがあればよいのですけどね。

前の関連記事:Calc(91)追加できるリスナー一覧: その11 変化を検知するリスナー


印刷1ページに収まる幅の調整


ページ幅に収まるように列幅を調整します。

印刷するページ幅を取得します。
 doc = XSCRIPTCONTEXT.getDocument()
 defaultpagestyle = doc.getStyleFamilies()["PageStyles"]["Default"]
 width, leftmargin, rightmargin = defaultpagestyle.getPropertyValues(("Width", "LeftMargin", "RightMargin"))
 pagewidth = width - leftmargin - rightmargin - 5  # 印刷幅を1/100mmで取得。なぜかはみ出るのでマージンを取る。 
デフォルトページスタイルから用紙幅を取得して、ページの左右の余白を除くと印刷幅が1/100mm単位で取得できます。

列幅も1/100mm単位で設定するので、1ページに収めたい列幅の合計が印刷幅内になるように列幅を設定すれば1ページ内に印刷されるはずですが、そのままにすると1列はみ出たので、5/100mm小さめに設定してます。

印刷1ページに収まる高さの調整


高さの場合は、幅と違って、ヘッダーとかフッターの高さも考慮しないといけません。

1ページにすべての行を収めるのではなく、1ページに収まる行ごとに改ページを挿入します。

つまりはデフォルトで挿入される改ページと同じことをしています。
def macro():
 doc = XSCRIPTCONTEXT.getDocument()
 defaultpagestyle = doc.getStyleFamilies()["PageStyles"]["Default"]
 properties = "Height", "TopMargin", "BottomMargin", "HeaderIsOn", "HeaderHeight", "FooterIsOn", "FooterHeight"
 height, topmargin, bottommargin, headerison, headerheight, footerison, footerheight = defaultpagestyle.getPropertyValues(properties)
 pageheight = height - topmargin - bottommargin  # 印刷高さを1/100mmで取得。
 if headerison:  # ヘッダーがあるときヘッダーの高さを除く。
  pageheight -= headerheight
 if footerison:  # フッターがあるときフッターの高さを除く。
  pageheight -= footerheight
 controller = doc.getCurrentController()
 sheet = controller.getActiveSheet()
 cursor = sheet.createCursorByRange(sheet["A1"])  # A1セルのセルカーサーを取得。
 cursor.gotoEndOfUsedArea(True)  # 使用範囲の右下のセルにセル範囲を拡大する。
 rows = cursor.getRows()  # 使用範囲の行コレクションを取得。
 rowheight = rows.getPropertyValue("Height")  # 1行の高さを取得。
 rowsperpage = pageheight//rowheight  # 1ページあたりの行数を取得。
 rows.setPropertyValue("IsStartOfNewPage", False)  # すでにある改ページを消去。
 for i in range(rowsperpage, len(rows), rowsperpage):  # 1ページあたりの行数毎に改ページを設定。
  rows[i].setPropertyValue("IsStartOfNewPage", True) 
すべての行の高さが同一のときはこれでうまくいきそうですが、高さが異なる行があるとうまくいきません。
def macro():
 doc = XSCRIPTCONTEXT.getDocument()
 defaultpagestyle = doc.getStyleFamilies()["PageStyles"]["Default"]
 properties = "Height", "TopMargin", "BottomMargin", "HeaderIsOn", "HeaderHeight", "FooterIsOn", "FooterHeight"
 height, topmargin, bottommargin, headerison, headerheight, footerison, footerheight = defaultpagestyle.getPropertyValues(properties)
 pageheight = height - topmargin - bottommargin  # 印刷高さを1/100mmで取得。
 if headerison:  # ヘッダーがあるときヘッダーの高さを除く。
  pageheight -= headerheight
 if footerison:  # フッターがあるときフッターの高さを除く。
  pageheight -= footerheight
 controller = doc.getCurrentController()
 sheet = controller.getActiveSheet()
 cursor = sheet.createCursorByRange(sheet["A1"])  # A1セルのセルカーサーを取得。
 cursor.gotoEndOfUsedArea(True)  # 使用範囲の右下のセルにセル範囲を拡大する。
 rows = cursor.getRows()  # 使用範囲の行コレクションを取得。
 rows.setPropertyValue("IsStartOfNewPage", False)  # すでにある改ページを消去。
 h = 0  # 行の高さの合計。
 for i in rows:  # 使用範囲の行をイテレート。
  rowheight = i.getPropertyValue("Height")  # 行の高さを取得。
  h += rowheight  # 行の高さを加算する。
  if h>pageheight:  # 1ページあたりの高さを越えた時。
   i.setPropertyValue("IsStartOfNewPage", True)  # 改ページを挿入。
   h = rowheight  # 行の高さをリセット。
行の高さを一つずつ加算して、1ページあたりの高さを越えたところで改ページを挿入しています。

行の高さを逐一取得して加算しているので時間がかかりますが、今のところもっとうまい方法が思いつきません。

2行ずつ結合している場合、結合セルが分割されないように改ページを挿入する


これはデフォルトの改ページで調整する方法がわからなかったので、マクロで対応することにしました。
def macro():
 doc = XSCRIPTCONTEXT.getDocument()
 defaultpagestyle = doc.getStyleFamilies()["PageStyles"]["Default"]
 properties = "Height", "TopMargin", "BottomMargin", "HeaderIsOn", "HeaderHeight", "FooterIsOn", "FooterHeight"
 height, topmargin, bottommargin, headerison, headerheight, footerison, footerheight = defaultpagestyle.getPropertyValues(properties)
 pageheight = height - topmargin - bottommargin  # 印刷高さを1/100mmで取得。
 if headerison:  # ヘッダーがあるときヘッダーの高さを除く。
  pageheight -= headerheight
 if footerison:  # フッターがあるときフッターの高さを除く。
  pageheight -= footerheight
 controller = doc.getCurrentController()
 sheet = controller.getActiveSheet()
 cursor = sheet.createCursorByRange(sheet["A1"])  # A1セルのセルカーサーを取得。
 cursor.gotoEndOfUsedArea(True)  # 使用範囲の右下のセルにセル範囲を拡大する。
 rows = cursor.getRows()  # 使用範囲の行コレクションを取得。
 rows.setPropertyValue("IsStartOfNewPage", False)  # すでにある改ページを消去。
 h = 0  # 行の高さの合計。
 for i in range(len(rows)):  # 行インデックスをイテレート。
  rowheight = rows[i].getPropertyValue("Height")  # 行の高さを取得。
  h += rowheight  # 行の高さを加算する。
  if h>pageheight:  # 1ページあたりの高さを越えた時。
   if i%2:  # 行インデックスが奇数の時。2で割り切れると0になるのでFalseになる。
    rows[i-1].setPropertyValue("IsStartOfNewPage", True)  # 一つ上の行に改ページを挿入。
    h = rows[i-1].getPropertyValue("Height") + rowheight  # 行の高さをリセット。  
   else:  # 行インデックスが偶数の時。
    rows[i].setPropertyValue("IsStartOfNewPage", True)  # 改ページを挿入。
    h = rowheight   # 行の高さをリセット。 
これはすべての行で2行ずつ結合しているセルがある場合を想定して、行インデックスが奇数の行では改ページが挿入されないようにしています。
def macro():
 doc = XSCRIPTCONTEXT.getDocument()
 defaultpagestyle = doc.getStyleFamilies()["PageStyles"]["Default"]
 properties = "Height", "TopMargin", "BottomMargin", "HeaderIsOn", "HeaderHeight", "FooterIsOn", "FooterHeight"
 height, topmargin, bottommargin, headerison, headerheight, footerison, footerheight = defaultpagestyle.getPropertyValues(properties)
 pageheight = height - topmargin - bottommargin  # 印刷高さを1/100mmで取得。
 if headerison:  # ヘッダーがあるときヘッダーの高さを除く。
  pageheight -= headerheight
 if footerison:  # フッターがあるときフッターの高さを除く。
  pageheight -= footerheight
 controller = doc.getCurrentController()
 sheet = controller.getActiveSheet()
 cursor = sheet.createCursorByRange(sheet["A1"])  # A1セルのセルカーサーを取得。
 cursor.gotoEndOfUsedArea(True)  # 使用範囲の右下のセルにセル範囲を拡大する。
 rows = cursor.getRows()  # 使用範囲の行コレクションを取得。
 rows.setPropertyValue("IsStartOfNewPage", False)  # すでにある改ページを消去。
 h = 0  # 行の高さの合計。
 for i in range(0, len(rows), 2):  # 偶数の行インデックスをイテレート。
  rowheight = rows[i].getPropertyValue("Height") + rows[i+1].getPropertyValue("Height")  # 行の高さを取得。
  h += rowheight  # 行の高さを加算する。
  if h>pageheight:  # 1ページあたりの高さを越えた時。
   rows[i].setPropertyValue("IsStartOfNewPage", True)  # 改ページを挿入。
   h = rowheight   # 行の高さをリセット。 
偶数の行インデックスだけをイテレートするように改善しました。

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ