2015年5月21日木曜日

ActiveReports.NET9.0Jを使ってAzure Web AppsでPDFを生成する

Azure Webサイト(いまはWeb Appsでした)で運用しているASP.NET WebAPIでPDFを生成できるか試してみました。


コンポーネント: ActiveReports.NET 9.0J Professional (グレープシティ)
フレームワーク: .NET 4.5.1 ASP.NET MVC Web API 2
言語: VB.NET

9.0JではAzureに対応するとされていますが,"Microsoft Azure Virtual Machines"とあるので,Webサイトではどうかなと気になっていました。

まず,参照を追加します。すべてローカルにコピーするようにします。


"Reports"というフォルダーを作成して,その中にレポートファイルを作成します。テストなのでレポートはテキストラベルでも貼り付けて適当に作ります。ファイル名は以下のようにしました。

ページレポート: PageReport1.rdlx
セクションレポート: SectionReport1.vb


"Controllers"フォルダーの中に"ReportController.vb"を作成します。コードは以下のようなかんじです。


Imports System.Net
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Web.Http
Imports GrapeCity.ActiveReports
Imports GrapeCity.ActiveReports.Export.Pdf.Page


Public Class ReportController
    Inherits ApiController

     
    Public Function GetPagePdfTest() As HttpResponseMessage

        Dim res As New HttpResponseMessage(HttpStatusCode.OK)
        Dim rptpath = System.Web.Hosting.HostingEnvironment.MapPath("~/Reports/PageReport1.rdlx")
        Dim rpt = New PageReport(New System.IO.FileInfo(rptpath))
        Dim doc As Document.PageDocument

        Try
            doc = New Document.PageDocument(rpt)
        Catch eRunReport As ReportException
            res.StatusCode = HttpStatusCode.InternalServerError
            Return res
        End Try

        Dim pdfRenderingExtension As New PdfRenderingExtension()
        Dim outputProvider As New Rendering.IO.MemoryStreamProvider()
        doc.Render(pdfRenderingExtension, outputProvider)

        res.Headers.Add("ContentType", "application/pdf")
        Dim ms As New System.IO.MemoryStream()
        CType(outputProvider.GetPrimaryStream().OpenStream(), System.IO.MemoryStream).WriteTo(ms)
        res.Content = New ByteArrayContent(ms.ToArray)
        res.Content.Headers.ContentDisposition = New ContentDispositionHeaderValue("attachment")
        res.Content.Headers.ContentDisposition.FileName = "pagereport.pdf"
        res.Content.Headers.ContentType = New MediaTypeHeaderValue("application/pdf")

        Return res

    End Function

     
    Public Function GetSectionPdfTest() As HttpResponseMessage

        Dim res As New HttpResponseMessage(HttpStatusCode.OK)
        Dim rpt As New SectionReport1

        Try
            rpt.Run()
        Catch ex As ReportException
            res.StatusCode = HttpStatusCode.InternalServerError
            Return res
        End Try

        Dim ms As New System.IO.MemoryStream()
        Dim export As New Export.Pdf.Section.PdfExport

        Try
            export.Export(rpt.Document, ms)
        Catch ex As ReportException
            res.StatusCode = HttpStatusCode.InternalServerError
            Return res
        End Try

        res.Headers.Add("ContentType", "application/pdf")
        res.Content = New ByteArrayContent(ms.ToArray)
        res.Content.Headers.ContentDisposition = New ContentDispositionHeaderValue("attachment")
        res.Content.Headers.ContentDisposition.FileName = "sectionreport.pdf"
        res.Content.Headers.ContentType = New MediaTypeHeaderValue("application/pdf")

        Return res

    End Function

End Class

Azure Webサイトに発行し,それぞれのレポートに対応するURLにアクセスするとPDFを取得できます。

ページレポート: https://hoge.azurewebsites.net/api/report/pagepdftest
セクションレポート: https://hoge.azurewebsites.net/api/report/sectionpdftest

ちなみに,ベーシックプラン以上だとうまくいきますが,共有プランではエラーが発生します。リモートデバッガーで簡単にエラーを調査できるので.NETを使うのであればAzure Webサイトはとても楽だと思いました。

あと,ActiveReportsをサーバーで運用するにはコア数に応じてコアサーバーライセンスが必要です。クラウドはコア数を簡単に変えられるので,ライセンスに注意ですね。