Webサービスで起業を目指すプログラマーblog

仕事で使ったプログラミング、サーバー周りで役に立つこと、Webサービス開発に必要な技術情報、モバイル情報を書いてます。わかりやすく見やすくをモットーにしています。

CrystalReportsでプリンター名を設定する方法

CrystalReportsで任意で選択したプリンターで印刷を行いたい場合、通常のプリンター指定では認識されないようです。

認識させるには、少し特殊な指定が必要なようです。

動作環境

Windows 10
VisualStudio Community 2015 Update3
.NETFramework 4.6.1
CrystalReports 13.0.20

通常の設定方法

こちらの設定で行っても指定したプリンターで印刷はされません。

public void Print(PrinterSettings settings)

    // デザイナーで定義したレポート
    TestReport r = new TestReport();
    r.Load();
    r.Refresh();

    // 給紙トレイ設定
    r.PrinterOptions.CustomPaperSource = settings.DefaultPageSettings.PaperSource;

    // プリンター名設定
    r.PrinterOptions.PrinterName = settings.PrinterName; // ←設定されない!!

    // 印刷実行
    r.PrintToPrinter(printer.Copies, false, 0, 0);
}

正しい設定方法

1.プロジェクトの参照からアセンブリタブにある4項目を追加する

  • CrystalDecisions.ReportAppServer.ClientDoc
  • CrystalDecisions.ReportAppServer.Controllers
  • CrystalDecisions.ReportAppServer.DataDefModel
  • CrystalDecisions.ReportAppServer.ReportDefModel


2.プリンター名の設定方法を次のように変更する

public void Print(PrinterSettings settings)

    // デザイナーで定義したレポート
    TestReport r = new TestReport();
    r.Load();
    r.Refresh();

    // 給紙トレイ設定
    r.PrinterOptions.CustomPaperSource = settings.DefaultPageSettings.PaperSource;

    // プリンター名設定
    // r.PrinterOptions.PrinterName = settings.PrinterName;
    ISCDReportClientDocument cdoc = r.ReportClientDocument;
    cdoc.PrintOutputController.GetPrintOptions().PrinterName = printer.PrinterName;

    // 印刷実行
    r.PrintToPrinter(printer.Copies, false, 0, 0);
}

VisualStudioのCrystalReportsを配布先のクライアントで動作させる手順

VisualStudioでCrystalReportsを使った開発を行うには「SAP Crystal Reports developer version for Visual Studio」が必要です。
これをインストールすれば開発環境では、問題なく動作します。

しかし、配布するとそのままでは動作しません。
配布先で動作させるためには、CrystalReportsのランタイム「SAP Crystal Reports Runtime」とインストーラーに「SAP Crystal Reports Runtime - Merge Modules」が必要です。

動作環境

開発環境

Windows 10
VisualStudio Community 2015 Update3
.NETFramework 4.6.1
CrystalReports 13.0.20

配布先

Windows 10
CrystalReports 13.0.20

VisualStudioのインストーラーでCrystalReportsのMergeModulesを適用する

VisualStuidoでインストーラーを扱うには、次の記事を参考にして下さい。
shinsuke789.hatenablog.jp


1.次のURLにアクセスし「SAP Crystal Reports Runtime - Merge Modules」をダウンロードします。

http://www.crystalreports.com/crvs/confirm/

f:id:shinsuke789:20171017094231j:plain


2.ダウンロードしたファイルを解凍し、「CRRuntime_13_0_xx.msm」と「CRRuntime_13_0_xx_ja.msm」のファイルを次の場所にコピーします。
f:id:shinsuke789:20171017094240j:plain

C:\Program Files (x86)\Common Files\Merge Modules

※コピーしなくても動作しますが、ここにコピーしておいた方が使い勝手が良いので

日本語環境なので「ja」のファイルを選択しています。動作環境に言語に合わせて適切なものを選択して下さい。


3.VisualStudioのセットアッププロジェクトを右クリックし、「Add」→「Merge Module...」をクリックします。
f:id:shinsuke789:20171017094256j:plain

4.ファイル選択ダイアログが表示されるので、2のファイルを選択し、プロジェクトに追加します。
f:id:shinsuke789:20171017094411j:plain


5.セットアッププロジェクトをビルドします。いつもより少し時間がかかります。


6.ビルドして生成されたインストーラーを配布します。

配布先には事前にCrystalReportsランタイムがインストールされている必要があります。

配布先でCrystalReportsのランタイムをインストールする

1.次のURLにアクセスし「SAP Crystal Reports Runtime (32Bit)」または「SAP Crystal Reports Runtime (64Bit)」をダウンロードします。

http://www.crystalreports.com/crvs/confirm/

f:id:shinsuke789:20171017092649j:plain


2.ダウンロードしたファイルを解凍し、インストーラーを実行します。
f:id:shinsuke789:20171017092712j:plain


3.ウィザードが開始されるので「Next」をクリックします。
f:id:shinsuke789:20171017092721j:plain


4.「I accept the License Agreement」を選択し、「Next」をクリックします。
f:id:shinsuke789:20171017092730j:plain


5.「Next」をクリックします。
f:id:shinsuke789:20171017092737j:plain


6.インストールが終わるまでしばらく待ちます。
f:id:shinsuke789:20171017092752j:plain


7.「Finish」をクリックし、インストールを終了します。
f:id:shinsuke789:20171017092803j:plain

配布先でのエラー対応

ファイルが見つからない

ファイルまたはアセンブリ'CrystalDecisions,CrystalReports.Engine, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=xxxxxxxx,またはその依存関係の1つが読み込めませんでした。指定されたファイルが見つかりません。

エラーメッセージに表示されている「Version」のCrystalReportsランタイムがインストールされていないのが原因です。
この場合、13.0.20のランタイムをインストールすることでエラーは解消します。

初期化子例外

'CrystalDecisions,CrystalReports.Engine.ReportDocument' のタイプ初期化子が例外をスローしました。System.TypeInitializationException

アプリケーションが、MergeModuleを適用したインストーラーでインストールされていないのが原因です。
MergeModuleを適用したインストーラーを作成してインストールしなおせば解消します。

旧バージョンのランタイムをダウンロードする

ランタイム配布サイトでは、最新版しかダウンロードできないと思われますが、URLを書き換えることで可能です。

URLのバージョンを希望のものに変更し、?以降を削除します。

最新版
http://downloads.businessobjects.com/akdlm/cr4vs2010/CRforVS_redist_install_32bit_13_0_21.zip?_ga=2.242728192.309491126.1508199297-555278125.1508199297

旧版
http://downloads.businessobjects.com/akdlm/cr4vs2010/CRforVS_redist_install_32bit_13_0_20.zip

SpringBootのJacksonで日付フォーマットを設定する方法

SpringBootのコントローラーの戻り値に@ResponseBodyを設定して、オブジェクトでJSONを返すとき、日付型はlongで扱われます。
それを適切は日付フォーマットにするには、設定ファイル、アノテーションで設定できます。

application.propertiesによる設定

アプリケーション全体の設定として適用されます。
タイムゾーン設定をしないと、日付がずれるので必ず設定しておきましょう。

application.properties

spring.jackson.date-format=yyyy/MM/dd'T'HH:mm:ss.SSSZ
spring.jackson.time-zone=Asia/Tokyo

アノテーションによる設定

JSONマッピングするオブジェクトクラスの日付フィールドで@JsonFormatアノテーションを設定します。
アノテーションでもタイムゾーンの設定ができます。

オブジェクトクラス

@JsonFormat(pattern = "yyyy/MM/dd")
private Date date;

@JsonFormat(pattern = "yyyy/MM/dd", timezone = "Asia/Tokyo")
private Date date;

PostgreSQLを自己証明書でSSLに対応する

手順通りにすれば、簡単にPostgreSQLSSLに対応できます。

動作環境

OS CentOS 6.4
PostgreSQL 9.3.2
OpenSSL 1.0.1e-fips 11 Feb 2013

自己証明書を作成する

1.PostgreSQLのdataディレクトリに移動する

$ cd /var/lib/pgsql/9.3/data

2.OpenSSLでRSA秘密鍵を作成する

# 2048はビット数
$ openssl genrsa 2048 > server.key

3.OpenSSLでCSRを作成する

$ openssl req -new -key server.key > server.csr

4.OpenSSLで証明書を作成する

# 36500は有効期限(この場合100年)
$ openssl x509 -days 36500 -req -signkey server.key < server.csr > server.crt 

5.作成したファイルの所有権・グループを変更する

$ chown postgres:postgres server.*

6.server.keyのアクセス権限を変更する

$ chmod 600 server.key

PostgreSQLの設定を変更する

1.pg_hba.confでアクセス権を変更する

$ vi /var/lib/pgsql/9.3/data/pg_hba.conf

# IPv4 local connections:
host     all     all     127.0.0.1/32     md5  # ローカルはSSL不要
hostssl     all     all     0.0.0.0/0     md5  # リモートはSSL必須

2.postgresql.confでSSLを有効にする

$ vi /var/lib/pgsql/9.3/data/postgresql.conf

# コメントアウトされているので、コメントを外し「ssl = on」にする
# ssl = off
ssl = on

3.設定を有効にするためPostgreSQLを再起動する

$ service postgresql-9.3 restart

注意事項

TomcatGlassFishなどのアプリケーションサーバーを利用している場合、PostgreSQLを再起動する前に停止しておく必要があります。
起動したままだと、データベースとの連携が行われなくなり接続エラーが発生します。

PostgreSQLの再起動が失敗した場合、エラーメッセージがログに出力されるので、そちらを参照し問題点を修正して下さい。
pg_logディレクトリ内に発生曜日ごとにログがあります。

/var/lib/pgsql/9.3/data/pg_log

SSL設定後のPostgreSQLへの接続

GUIツールは、SSLの設定を追加して接続するだけです。

psqlコマンドで接続する場合、接続情報を「""」で括り、「sslmode=require」を追加します。

psql "sslmode=require host=xxx.xxx.xxx.xxx user=user1 dbname=db1"

SSL設定後のアプリケーション側での接続文字列変更

Java

接続文字列に「?sslmode=require」を追加します。

jdbc:postgresql://xxx.xxx.xxx.xxx:5432/dbname?sslmode=require

.NET

接続文字列に「SSL Mode = true; Trust Server Certificate = true; 」を追加します。

Host=xxx.xxx.xxx;Database=dbname;Username=user;Password=pass;SSL Mode=Require;Trust Server Certificate=True

PostgreSQLを深く知るためにおすすめの書籍

内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)

内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)

PostgreSQL全機能バイブル

PostgreSQL全機能バイブル

Thymeleaf2.xでの「少し困った!」に役立つミニリファレンス集

Thymeleafを使用した開発で、実際に少し困ったことについてまとめてみました。

これから利用する方の役に立てればと思います。

リンクにパラメーターを含める

変数${}の前後に__を追加し、__${}__の形にする。

<a th:href=“@{/hoge/__${e.no}__/add}">hoge</a>

formタグのactionに文字列変数を展開する

変数に定義した文字列をリンクとして展開する場合、@{}内に${}で変数を定義する。

<!-- 通常の文字指定 -->
<form th:action=“@{/hoge}” method=“post”>

<!-- 変数指定 -->
<form th:action=“@{${hoge}}” method=“post”>

「data-」属性に値を設定する

<span th:attr="data-hoge=${hoge}">hoge</span>

変数を含んだ文字列の展開

「|」で括る

<span th:text=“|${hoge}です。|”/>

JavaScriptで変数を扱う

<script>タグにth:inline="javascript"を追加し、/*<![CDATA[*//*]]>*/で括る。
その中での変数は、/*[[]]*/で括る。

<script th:inline="javascript">
/*<![CDATA[*/
    /*[[@{/hoge}]]*/
/*]]>*/
</script>

JavaScriptで変数を文字で連結する

変数を/*[++]*/で括る。

<script th:inline="javascript">
/*<![CDATA[*/
    var val = "aaa" + /*[+ [[${hoge}]]  +]*/;
/*]]>*/
</script>

比較演算子

Thymeleafでは、比較演算子がそのままでは使えないので、次の標記を使用する。

> gt
< lt
>= ge
<= le

Thymeleafの記載がある書籍

c#のアプリケーション設定でプリンタ設定(PrinterSettings)を保存・読み込みできるようにする

c#でプリンターの設定(PrinterSettings)を保存する必要があったので、アプリケーション設定で保存するようしました。

しかし、アプリケーションが起動している最中は、設定の読み込み・保存が有効でも、アプリケーションを再起動すると設定が読み込まれない問題に遭遇しました。

いろいろ試した所、標準のやり方ではなく、手動でコードを書く必要があったのでその方法をまとめました。

手順

1.アプリケーション設定で通常通り設定を宣言している場合、削除します
f:id:shinsuke789:20170922101522p:plain

2.アプリケーション設定の上部にある「コードの表示」をクリックします
f:id:shinsuke789:20170922101525p:plain

3.設定用のコードが表示されるので、クラス内に設定名のプロパティで次のようなコードを追記します

[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsSerializeAsAttribute(SettingsSerializeAs.Binary)]
public PrinterSettings Printer
{
    get
    {
        return ((PrinterSettings)(this["Printer"]));
    }
    set
    {
        this["Printer"] = value;
    }
}

この場合は、PrinterSettingsという型で保存を行います。
プロパティ名・get/setの[]内には設定名を宣言します。

通常のアプリケーション設定で宣言するとXMLで保存され、それが読み込まれないので設定が復元できないようです。
それを回避するため、上記コードの2行目にある[global::System.Configuration.SettingsSerializeAsAttribute(SettingsSerializeAs.Binary)]を追加してバイナリで保存するようにします。

単純なプロパティのみのクラスで試した所、XML形式で保存され、読み込み・保存とも可能でした。
ひょっとすると一定の階層を超えると復元できないのかもしれません。

4.設定の読み込み・保存は通常通りのコードで可能です。

// 読み込み
PrinterSettings p = Settings.Default.Printer;

// 保存
Settings.Default.Printer = printerSettings;
Settings.Default.Save();

まとめ

stringやintと同じような形でPrinterSettingsを保存しようとして、1日ぐらい悩みました。
こういうときは一晩おくと冷静になって解決方法が見つかるんですよね。

そのおかけでなんとか解決することができました。

基本的にアプリケーション設定にない型を保存する場合は、手動でプロパティを宣言しバイナリで保存するようにした方が良いでしょう。

参考

調査していると、プリンターの設定方法を質問しているページがあったので参考にしました。
やはり同じようにアプリケーションを再起動すると読み込まれないと書かれています。

c# - how to Save PrintDocument .PrinterSettings in a file so that user have not to select printer settings everytime? - Stack Overflow

上記サイトは、base64に変換して保存・読み込みする方法でしたが、そんなことしなくてもバイナリ設定で解決です。

現場ですぐに使える!  VisualBasic 2015 逆引き大全 520の極意

現場ですぐに使える! VisualBasic 2015 逆引き大全 520の極意

MacでJavaのインストールとバージョンの切り替えを行う

Javaのインストール

1.OracleサイトよりMac版のJDK単体をダウンロードします

Java SE Development Kit 8 - Downloads

2.ダウンロードしたdmgファイルを実行し、インストールを行います

3.ターミナルを起動し、Javaのバージョンを確認します

$ java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

Javaの切り替え

Macでは複数バージョンのJavaをインストールできます。

1.ターミナルを起動し、現在インストールされているJavaの一覧を表示します

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
    1.8.0_144, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
    1.7.0_80, x86_64:	"Java SE 7"	/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
    1.6.0_65-b14-468, x86_64:	"Java SE 6"	/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_65-b14-468, i386:	"Java SE 6"	/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

2.現在使用されているJavaのバージョンを確認します。

$ java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

3.「.bash_profile」に環境変数JAVA_HOME」を追加し、使用するJavaバージョンを指定します。

$ vi ~/.bash_profile

# 以下を追記する、下記の1.7を1.6等に変更するとそのバージョンに変わる
export JAVA_HOME=$(/usr/libexec/java_home -v 1.7)
export PATH=${JAVA_HOME}:${PATH}

4.「.bash_profile」を再ロードして設定を有効に、Javaバージョンが変わっているか確認します

$ source ~/.bash_profile
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

元のバージョンに戻すには、「.bash_profile」に追加した環境変数を削除またはコメントアウトし、再ロードすれば戻ります。

Javaのアンインストール

Javaをインストールすると追加でインストールされ、古いJavaが残ったままになるので、その都度削除が必要です。

1.ターミナルを起動し、現在インストールされているJavaの一覧を表示します

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
    1.8.0_144, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
    1.7.0_80, x86_64:	"Java SE 7"	/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
    1.6.0_65-b14-468, x86_64:	"Java SE 6"	/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_65-b14-468, i386:	"Java SE 6"	/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

2.削除コマンドを使って削除したいJavaのパスを指定し、削除します

$ rm -Rf /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk