ASP.NET MVC で WebForms の Chart を使って作成したチャートを PDF に埋め込む

ASP.NET MVC で System.Web.UI.DataVisualization.Charting.Chart を使って、 レーダーチャートをカスタマイズできるところまでは確認できた。

tnakamura.hatenablog.com

今度は iTextSharp と組み合わせて、 レーダーチャートを PDF に埋め込めるかどうかを試してみる。 多分、System.Web.Helpers.Chart と同じようにできると思うけど、念のため。

using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Drawing;
using System.IO;
using System.Web.Mvc;
using System.Web.UI.DataVisualization.Charting;

namespace MvcWebFormChartPdfSample.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Pdf()
        {
            var pdfData = CreatePdf();
            return File(pdfData, "application/pdf", "PDFSample.pdf");
        }

        // PDF(バイナリ)を作成
        private byte[] CreatePdf()
        {
            using (var document = new Document(PageSize.A4, 20, 20, 20, 20))
            using (var stream = new MemoryStream())
            using (var writer = PdfWriter.GetInstance(document, stream))
            {
                document.Open();

                // テキストを PDF に書き込む
                document.Add(new Paragraph("PDF Sample"));

                // レーダーチャート画像を PDF に埋め込む
                var chart = CreateChartData();
                var image = iTextSharp.text.Image.GetInstance(chart);
                document.Add(image);

                document.Close();

                return stream.ToArray();
            }
        }

        private byte[] CreateChartData()
        {
            var chart = new Chart
            {
                Height = 450,
                Width = 600,
                ImageType = ChartImageType.Png,
                ChartAreas =
                {
                    new ChartArea
                    {
                        Name = "Default",
                        AxisY = new Axis
                        {
                            Maximum = 100,
                            IsStartedFromZero = true,
                            CustomLabels =
                            {
                                new CustomLabel
                                {
                                    Text = "A",
                                    FromPosition = 95,
                                    ToPosition = 105
                                },
                                new CustomLabel
                                {
                                    Text = "B",
                                    FromPosition = 75,
                                    ToPosition = 85
                                },
                                new CustomLabel
                                {
                                    Text = "C",
                                    FromPosition = 55,
                                    ToPosition = 65
                                },
                                new CustomLabel
                                {
                                    Text = "D",
                                    FromPosition = 35,
                                    ToPosition = 45
                                },
                                new CustomLabel
                                {
                                    Text = "E",
                                    FromPosition = 15,
                                    ToPosition = 25
                                },
                                new CustomLabel
                                {
                                    Text = "F",
                                    FromPosition = -5,
                                    ToPosition = 5
                                }
                            }
                        }
                    }
                },
                Legends =
                {
                    new Legend
                    {
                        Title = "凡例"
                    }
                },
                Series =
                {
                    new Series
                    {
                        Name = "サンプル1",
                        ChartType = SeriesChartType.Radar,
                        Color = Color.FromArgb(100, 151, 187, 205),
                        MarkerStyle = MarkerStyle.Circle,
                        MarkerColor = Color.FromArgb(151, 187, 205),
                        BorderWidth = 2,
                        BorderColor = Color.FromArgb(151, 187, 205),
                        Points =
                        {
                            new DataPoint
                            {
                                AxisLabel = "ミート",
                                YValues = new double[] { 90 }
                            },
                            new DataPoint
                            {
                                AxisLabel = "パワー",
                                YValues = new double[] { 80 }
                            },
                            new DataPoint
                            {
                                AxisLabel = "走力",
                                YValues = new double[] { 70 }
                            },
                            new DataPoint
                            {
                                AxisLabel = "肩力",
                                YValues = new double[] { 60 }
                            },
                            new DataPoint
                            {
                                AxisLabel = "守備力",
                                YValues = new double[] { 80 }
                            }
                        }
                    }
                }
            };

            using (var stream = new MemoryStream())
            {
                chart.SaveImage(stream);
                return stream.ToArray();
            }
        }
    }
}

Web ブラウザからこのアクションを呼び出すと、 次のような PDF ファイルをダウンロードできた。

f:id:griefworker:20150527134118p:plain

予想通り。