FpSpreadをサーバー処理で使用してみた【VB.NET】

こんにちは、Loxyです。
普段はPHP案件ばかりやっているのですが、次の案件まで空きがでてVBチームの手伝いしてます。
さて表題の件、おそらくこのような使い方をするのはかなりレアケースだと思いますが、
過去の自分へ向けて、そして悩めるプログラマさんのお役に立てればと思い残しておきます。



FpSpreadをサーバー処理で使用してみた【VB.NET】

GrapeCity / SPREAD for Windows Forms の説明は省きます。
.NETスプレッドシートコンポーネント - SPREAD for Windows Forms(スプレッド) | Developer Tools〈開発支援ツール〉 - グレープシティ株式会社

実現したかったこと

  1. Windowsフォームより、データ検索条件(今回は対象日付とデータに紐づくユーザーコード)を入力し、出力ボタンをクリック
  2. サーバー側で検索処理が実行され、抽出データを元にエクセル形式で帳票を作成する
  3. 作成したエクセルを別のサーバーへ保存

まぁ、割とよくある帳票出力系の機能ですね。

そもそも、なぜサーバー側でSpraedを使用?

これは、お客さんのわがままです。
昔はMicrosoft.Office.Interop.Excelを利用したり、現在であればサードパーティ・オープンソースのライブラリを使用するかと思います。(過去にExcel Creatorを使用したことがありますが、あれば使いやすかった気がします。)

ただ今回の案件、お客さんはスプレッドを使用した別システム運用中で、余ったライセンスがある。なので、スプレッドを利用して出力してほしい…との希望。
「別にスプレッドでなくてもええやん」と思いましたが、よくある節約によるエンジニア泣かせ事案です。

とは言え、言われたものは実現をさせていのがエンジニアというもの。何とかやってみました。

そもそもできるのか?

疑問はそこからです。
本来は、WindowsフォームやWeb上にエクセルライクな表を描画させることができるのがスプレッドの良さ。画面ありきです。
ヘルプも見まくったのですが、単にオブジェクトとしての利用は説明がありません。(僕は見つけられませんでした)
でも、動的にコントロールを生成するようなパターンなら、必ずしもスプレッドが初めからフォーム上にある必要はない
なので…できるだろうという結論。

※もちろん、開発マシンにはSpreadをインストールし、ライセンス認証を済ませた状態でスタート。

 

実際にやってみたこと

やってみた(失敗例)

とりあえず、サーバー側の対象のプロジェクトに必要そうなライブラリを参照追加。
  • FarPoint.Win
  • FarPoint.Win.SpreadJ
  • FarPoint.Win.Excel
  • FarPoint.Win.CalEngine(これも必要か?)
次に適当な場所でFpSpreadをオブジェクトとしてインスタンス化
Dim objFpSpread As New FarPoint.Win.Spread.FpSpread
実行してみると以下のエラー
アプリケーションが UserInteractive モードで実行されていないときに、モーダル ダイアログまたはフォームを表示することは有効な操作ではありません。
サービス アプリケーションからの通知を表示するには、ServiceNotification または DefaultDesktopOnly スタイルを指定してください。
モーダル、ダイアログまたはフォーム?何のこと?意味が分かりません。
その後試行錯誤するも全く状況が変わらず。イライラしたのでその日は帰宅しました。

 

やってみた(原因究明)

どうも原因がわからないので、とりあえず普通にフォーム側にSpreadコントロールを張って確認してみました。
すると…
アプリケーションにライセンスが付与されていません
のダイアログが表示されるではありませんか。
お前かよ、邪魔すんなと思いつつ、でもライセンス認証してるけど…と考えました。



ネットで情報を漁り、「licenses.licx」がプロジェクトに含まれていないと、上記のダイアログがでてしまう…との情報を何とか見つけました。

公式ヘルプには「Spread関係のコントロール(なんでも)をフォームに張り付ければlicenses.licxに勝手にできる」と書いてあったので、
探してみると、確かにファイルはあります。ただ、プロジェクトのMy Projectの内に
でも、その状態だと何度やっても上記のダイアログが表示されてしまったので、以下の手順で追加し直してみます。
  1. プロジェクトを右クリック
  2. 追加
  3. 既存の項目
  4. 「licenses.licx」を選択
  5. プロジェクト直下にライセンスファイルを配置
こうすることで、ライセンス付与のエラーメッセージは出なくなりました。
ちなみにライセンスファイルは手動で作成してもOKなようです。
製品ヘルプ→制限事項/ライセンスエラー→ライセンスエラーの対処方法→Csse5にやり方が記載されています。

 

やってみた(成功)

次は本題のサーバー側でのこと。これができなれれば意味がない。
先ほどと同じように、プロジェクトへライセンスファイルを追加し、ライブラリ参照も追加(念のため一旦消して再追加しました)
初めに記述しておいた
Dim objFpSpread As New FarPoint.Win.Spread.FpSpread
をデバッグ流してみると…成功!というかエラーは出ない。
これでようやくサーバー側でスプレッドをObjectとして生成し利用ができるようになりました。

使用例サンプル

今回のExcel出力の処理は
  1. テンプレートファイルを開く
  2. 必要な情報を追記
  3. 出力
という流れの処理を実装しました。サンプルを置いておきます。
'Spreadオブジェクトを生成
Dim objFpSpread As New FarPoint.Win.Spread.FpSpread

'テンプレートファイルを開く
objFpSpread.OpenExcel("ファイル名フルパス", "シート名")

'書式の入ったテンプレート行をコピー
objFpSpread.ActiveSheet.CopyRange
(コピー元行Index, コピー元列Index, コピー先行Index, コピー先列Index, コピーする行数, コピーする列数, データのみか否か)

'値をセット
objFpSpread.ActiveSheet.SetValue(行Index, 列Index, セットする値)'xlsx形式で保存
objFpSpread.SaveExcel("保存ファイルフルパス", FarPoint.Excel.ExcelSaveFlags.UseOOXMLFormat)

まとめ

正直レアなケースだと思いますので、頻出するわけではないと思います。
僕のようにお客さんのわがままを押し付けられた、プログラマーさんのお役に立てれば幸いです。
それでは! Have a happy hacking!