4
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Blazor Client-Sideアプリで帳票印刷する

Last updated at Posted at 2020-01-21

Blazor Client-Sideアプリで、帳票印刷アプリケーションの作成をしてみたいと思います。

今回は、paper.cssを使ってブラウザだけで名刺を印刷するで、実現されていることをオマージュ(最大限パクリ)させて頂き、Blazorに換装してみたいと思います。

Demo

サンプルコード
https://github.com/kimux8/BlazorAppPrint

概要

参照元サイト様のBlazor版です。JavaScript + CSSにより名刺印刷アプリを実現されています。

paper.cssを使ってブラウザだけで名刺を印刷する
https://qiita.com/okoppe8/items/abcafdad3a894bca7f38

また、参照元ではCSSフレームワークであるpaper.cssを活用されています。

paper.css
https://github.com/cognitom/paper-css

そろそろ真面目に、HTMLで帳票を描く話をしようか
https://qiita.com/cognitom/items/d39d5f19054c8c8fd592

今回は、移植するにあたり、はまったところ(帳票作成とあまり関係ないことも含め)を中心に記述していきたいと思います。

ページ間でのパラメータの渡し方について

Blazorでのページ遷移はいくつかやり方がありますが、NavigationManagerNavigateTo("リンク先")メソッドを使用する方法があります。パラメータが複数ある場合、複数のルートパラメータを指定することができますが、数が多すぎる場合、必要な情報を定義したクラスをSharedに定義してInjectして連携した方がスッキリします。

ルートパラメータによるパラメータ渡し

index.razor

@code{
    string p0 = @"営業推進部営業1課
シニアマネージャー";
    ...
    string p5 = @"〒100-8111
東京都千代田区千代田1-1
ロイヤルパレスパークビル 15F
電話: 03-1111-1111(代表) FAX: 03-2222-2222
携帯: 090-3333-3333
mail: kii-taichiro@dummy.lo.go.jp";

    void OnPrint()
    {
        // カッコ悪い
        navMgr.NavigateTo(string.Format("/print/{0}/{1}/{2}/{3}/{4}/{5}", p0, p1, p2, p3, p4, p5));
    }
}
Print.razor
@page "/print/{p0}/{p1}/{p2}/{p3}/{p4}/{p5}"

Injectによるパラメータ渡し

shared/Person.cs
namespace BlazorAppPrint.Shared
{
    public class Person
    {
        public string P0 { get; set; }
        public string P1 { get; set; }
        public string P2 { get; set; }
        public string P3 { get; set; }
        public string P4 { get; set; }
        public string P5 { get; set; }
        ....
    }
}
Startup.cs
using BlazorAppPrint.Shared;

namespace BlazorAppPrint
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<Person>(); // インスタンス化
        }
    }
}
index.razor
@page "/"

@inject NavigationManager  navMgr
@inject Person person
@code{
    protected override void OnInitialized()
    {
        person.P0 = @"営業推進部営業1課
シニアマネージャー";

        person.P1 = "きい";
        ...
        person.P5 = @"〒100-8111
東京都千代田区千代田1-1
ロイヤルパレスパークビル 15F
電話: 03-1111-1111(代表) FAX: 03-2222-2222
携帯: 090-3333-3333
mail: kii-taichiro@dummy.lo.go.jp";     
    }

    void OnPrint()
    {
        // すっきりー
        navMgr.NavigateTo("/print");
    }
}
Print.razor
@page "/print"
@inject Person person

CSS分離できない問題

Blazorでは、CSSなど静的ファイルは、wwwroot/index.htmlに記述します。ここに定義すると、すべてのページで読み込まれてしまうので、特定のページだけ適用したい!というのが難しいわけですね。これは、他のフレームワークからBlazorに移行しようとしたとき、大きな壁になるかもしれません。

今回はpaper.cssのCSSフレームワークを活用しているのですが、paper.cssを特定のページに適用することができないため静的リンクしていません。その為、参照元サイトでもそうですが、paper.cssの一部をsite.cssに移植しています。

CSS Isolation in Blazor Components
https://github.com/dotnet/aspnetcore/issues/10170

はじめからある不要なスタイルの削除

帳票デザインのページでは、絶対位置指定などベタに調整することがあると思います。Blazorではデフォルトプロジェクトから作成した時に、既にsite.cssに多くのスタイルが定義された状態であり、これらの定義が邪魔になることがあります。
今回は、appに定義されたスタイルをコメントアウトしています。

wwwroot/css/site.css
app {
    /*コメントアウト*/
    /*position: relative;
    display: flex;
    flex-direction: column;*/
}

Tableでは、子要素をコンポーネント化しない

今回のアプリケーションでは、名刺デザインが2つ(プレビュー用と印刷用)が登場しますが、Tableにより実装しています。ここをサクっとコンポーネント化すれば、繰り返し処理などはスッキリするのですが、Tableと中の要素(tr,td)を別コンポーネントする場合、下記のようなCSSでは効かないので、注意が必要です。

wwwroot/css/site.css
table.preview {
    position: relative;
    ...
    transform-origin: top;
}

    table.preview td {
        border: 1px solid;
        ...
        position: relative;
    }

table.preview tdを使用するときは、previewtdのコンポーネントは同じコンポーネントに書く。

Page.razor
<table class="preview">
  <tr>
    <td>...  ここを別コンポーネントにすると、CSSがめんどい
  </tr>  
</table>

既存のCSSを使いまわす場合、注意が必要ですね。

常に親ウィンドウ

印刷処理は、JavaScriptwindow.print()をコールしています。参照元サイトでは印刷のプレビュー画面が閉じられた後、印刷用ページのウィンドウを閉じるwindow.close()をコールしますが、今回は親ウィンドウ自体が印刷用の画面となる為、window.close()が使えません。その為、window.history.back(-1)により、前画面に遷移することで、同様の動作を行っています。

wwwroot/index.html
...
<body>
    ...
    <!--印刷ダイアログ表示用-->
    <script>
        window.printwindow = () => {
            setTimeout(function () {
                window.print();
                // windows.close()は使えないので、ひとつ前に戻る
                window.history.back(-1);
            }, 200);
            return true;
        }
    </script>
<body>

最後に

Blazorでの帳票印刷は、HTMLベースでの帳票作成が手っ取り早いです。とは言え、レポート作成のパッケージをゴリゴリ使用しているアプリケーションのBlazorへの移行などは、少々大変かもしれません。

4
11
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
4
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?