FlexGrid for WPF
PDFファイルを保存する
基本操作 > エクスポート > PDFファイルを保存する

C1FlexGrid のデータをPDFファイルにエクスポートする方法として、Helperクラス、たとえばGridExport、を使用してグリッドの内容をPDF内に描画する方法があります。具体的には、GridExportクラス内に SavePdf というメソッドで FlexGrid を PDFストリーム内に直接描画します。この方法は次のように簡単に実現できます。

また、ここはヘルパークラス内に RenderGrid というメソッドでグリッドを既存の C1PdfDocument 上に描画する方式も含みます。RenderGrid は、複数グリッドを文書に追加してグラフ、テキスト、画像と他のUI要素も組み合わせる場合よく使いこなします。詳細方法については、次に示すコードをご確認ください。以下に示す GridExport のヘルパークラスは必要に応じてカスタマイズできますので活用してみてください。

[実行例]

 

 

PDF ファイルを保存します

 

 

 サンプルコードは次のようになります。

 

コードのコピー
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // グリッドにデータを挿入します
        _flex1.ItemsSource = Product.GetProducts(20);           
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var dlg = new Microsoft.Win32.SaveFileDialog();
        dlg.Filter = "PDF files (*.pdf)|*.pdf";
        //var t = dlg.ShowDialog();
        if (dlg.ShowDialog().Value)
        {
            // PDF文書を作成します
            var pdf = new C1PdfDocument();
            pdf.Landscape = true;
            pdf.Compression = CompressionLevel.NoCompression;

            // グリッドをPDFに描画します
            var options = new PdfExportOptions();
            options.ScaleMode = ScaleMode.ActualSize;
            GridExport.RenderGrid(pdf, _flex1, options);
            pdf.NewPage();
    
            // 文書を保存します
            using (var stream = dlg.OpenFile())
            {
                pdf.Save(stream);
            }
        }
    }
}
コードのコピー
namespace MultiGridPdf
{
    internal static class GridExport
    {
        public static void SavePdf(C1FlexGrid flex, Stream s)
        {
            var options = new PdfExportOptions();
            SavePdf(flex, s, options);
        }
        public static void SavePdf(C1FlexGrid flex, Stream s, PdfExportOptions options)
        {
            var pdf = new C1PdfDocument();
            options.KnownPageCount = false;
            RenderGrid(pdf, flex, options);

            // PDF文書を保存してストリームを閉じます
            pdf.Save(s);
            s.Close();
        }

        public static void RenderGrid(C1PdfDocument pdf, C1FlexGrid flex)
        {
            RenderGrid(pdf, flex, null);
        }
        public static void RenderGrid(C1PdfDocument pdf, C1FlexGrid flex, PdfExportOptions options)
        {
            // 描画オプションを取得します
            if (options == null)
            {
                options = new PdfExportOptions();
            }

            // PDFページをレイアウトするためにルート要素を取得します
            Panel root = null;
            for (var parent = flex.Parent as FrameworkElement; parent != null; parent = parent.Parent as FrameworkElement)
            {
                if (parent is Panel)
                {
                    root = parent as Panel;
                }
            }

            // ページサイズを取得します
            var rc = pdf.PageRectangle;

            // 描画する間に要素を保持するためにパネルを作成します
            var pageTemplate = new PageTemplate();
            pageTemplate.Width = rc.Width;
            pageTemplate.Height = rc.Height;
            pageTemplate.SetPageMargin(options.Margin);
            root.Children.Add(pageTemplate);

            // PDF文書にグリッドを描画します
            var m = options.Margin;
            var sz = new Size(rc.Width - m.Left - m.Right, rc.Height - m.Top - m.Bottom);
            var pages = flex.GetPageImages(options.ScaleMode, sz, 100);
            for (int i = 0; i < pages.Count; i++)
            {
                // 必要な場合、ページをスキップします
                if (i > 0)
                {
                    pdf.NewPage();
                }

                // コンテンツを設定します
                pageTemplate.PageContent.Child = pages[i];
                pageTemplate.PageContent.Stretch = options.ScaleMode == ScaleMode.ActualSize
                    ? System.Windows.Media.Stretch.None
                    : System.Windows.Media.Stretch.Uniform;

                // ヘッダー・フッターのテキストを設定します
                pageTemplate.HeaderLeft.Text = options.DocumentTitle;
                if (options.KnownPageCount)
                {
                    pageTemplate.FooterRight.Text = string.Format("Page {0} of {1}",
                        pdf.CurrentPage + 1, pages.Count);
                }
                else
                {
                    pageTemplate.FooterRight.Text = string.Format("Page {0}",
                        pdf.CurrentPage + 1);
                }

                // ページの要素を測定します
                pageTemplate.UpdateLayout();
                pageTemplate.Arrange(new Rect(0, 0, rc.Width, rc.Height));

                // PDFに追加します
                pdf.DrawElement(pageTemplate, rc);
            }

            // テンプレート完了
            root.Children.Remove(pageTemplate);
        }

        
    }
}
コードのコピー
namespace MultiGridPdf
{
    public class PdfExportOptions
    {
        public PdfExportOptions()
        {
            Margin = new Thickness(96);
            ScaleMode = ScaleMode.PageWidth;
            DocumentTitle = "ComponentOne FlexGrid";
        }
        public Thickness Margin { get; set; }
        public ScaleMode ScaleMode { get; set; }
        public string DocumentTitle { get; set; }
        public bool KnownPageCount { get; set; }
    }
}
コードのコピー
<!-- ヘッダー -->
<Border Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" 
        Margin="0 12" 
        BorderBrush="Black"
        BorderThickness="0 0 0 1" >
    <Grid>
        <TextBlock x:Name="HeaderLeft" Text="ComponentOne FlexGrid" FontWeight="Bold" FontSize="14"
            VerticalAlignment="Bottom" HorizontalAlignment="Left" />
        <TextBlock x:Name="HeaderRight" Text="Printing Demo" FontWeight="Bold" FontSize="14" HorizontalAlignment="Right" Height="18" VerticalAlignment="Bottom" />
    </Grid>
</Border>

<!-- フッター -->
<Border Grid.Column="1" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Top" 
        Margin="0 12" 
        BorderBrush="Black"
        BorderThickness="0 1 0 0" >
    <Grid>
        <TextBlock x:Name="FooterLeft" Text="Today" 
            VerticalAlignment="Bottom" HorizontalAlignment="Left" />
        <TextBlock x:Name="FooterRight" Text="Page {0} of {1}" 
            VerticalAlignment="Bottom" HorizontalAlignment="Right" />
    </Grid>
</Border>

<!-- コンテンツ -->
<Viewbox Name="PageContent" Grid.Row="1" Grid.Column="1" 
    VerticalAlignment="Top" HorizontalAlignment="Left" />
コードのコピー
Class MainWindow
    Inherits Window
    Public Sub New()
        InitializeComponent()
        ' グリッドにデータを挿入します
        _flex1.ItemsSource = Product.GetProducts(10)
        _flex1.CollectionView.Filter = AddressOf FilterComputers

    End Sub

    Private Function FilterComputers(item As Object) As Boolean
        Dim p = TryCast(item, Product)
        Return p.Line = "Computers"
    End Function
    Private Function FilterStoves(item As Object) As Boolean
        Dim p = TryCast(item, Product)
        Return p.Line = "Stoves"
    End Function
    Private Function FilterWashers(item As Object) As Boolean
        Dim p = TryCast(item, Product)
        Return p.Line = "Washers"
    End Function
    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Dim dlg = New Microsoft.Win32.SaveFileDialog()
        dlg.Filter = "PDF files (*.pdf)|*.pdf"
        'var t = dlg.ShowDialog();
        If dlg.ShowDialog().Value Then
            ' PDF文書を作成します
            Dim pdf = New C1PdfDocument()
            pdf.Landscape = True
            pdf.Compression = CompressionLevel.NoCompression

            ' グリッドをPDFに描画します
            Dim options = New PdfExportOptions()
            options.ScaleMode = ScaleMode.ActualSize
            GridExport.RenderGrid(pdf, _flex1, options)

            ' 文書を保存します
            Using stream = dlg.OpenFile()
                pdf.Save(stream)
            End Using
        End If
    End Sub

End Class
コードのコピー
Public Class GridExport
    Public Shared Sub SavePdf(flex As C1FlexGrid, s As Stream)
        Dim options = New PdfExportOptions()
        SavePdf(flex, s, options)
    End Sub
    Public Shared Sub SavePdf(flex As C1FlexGrid, s As Stream, options As PdfExportOptions)
        Dim pdf = New C1PdfDocument()
        options.KnownPageCount = False
        RenderGrid(pdf, flex, options)

        ' PDF文書を保存してストリームを閉じます
        pdf.Save(s)
        s.Close()
    End Sub

    Public Shared Sub RenderGrid(pdf As C1PdfDocument, flex As C1FlexGrid)
        RenderGrid(pdf, flex, Nothing)
    End Sub
    Public Shared Sub RenderGrid(pdf As C1PdfDocument, flex As C1FlexGrid, options As PdfExportOptions)
        ' 描画オプションを取得します
        If options Is Nothing Then
            options = New PdfExportOptions()
        End If

        ' PDFページをレイアウトするためにルート要素を取得します
        Dim root As Panel = Nothing
        Dim parent = TryCast(flex.Parent, FrameworkElement)
        While parent IsNot Nothing
            If TypeOf parent Is Panel Then
                root = TryCast(parent, Panel)
            End If
            parent = TryCast(parent.Parent, FrameworkElement)
        End While

        ' ページサイズを取得します
        Dim rc = pdf.PageRectangle

        ' 描画する間に要素を保持するためにパネルを作成します
        Dim pageTemplate = New PageTemplate()
        pageTemplate.Width = rc.Width
        pageTemplate.Height = rc.Height
        pageTemplate.SetPageMargin(options.Margin)
        root.Children.Add(pageTemplate)

        ' PDF文書にグリッドを描画します
        Dim m = options.Margin
        Dim sz = New Size(rc.Width - m.Left - m.Right, rc.Height - m.Top - m.Bottom)
        Dim pages = flex.GetPageImages(options.ScaleMode, sz, 100)
        For i As Integer = 0 To pages.Count - 1
            ' 必要な場合、ページをスキップします
            If i > 0 Then
                pdf.NewPage()
            End If

            ' コンテンツを設定します
            pageTemplate.PageContent.Child = pages(i)
            pageTemplate.PageContent.Stretch = If(options.ScaleMode = ScaleMode.ActualSize, System.Windows.Media.Stretch.None, System.Windows.Media.Stretch.Uniform)

            ' ヘッダー・フッターのテキストを設定します
            pageTemplate.HeaderLeft.Text = options.DocumentTitle
            If options.KnownPageCount Then
                pageTemplate.FooterRight.Text = String.Format("Page {0} of {1}", pdf.CurrentPage + 1, pages.Count)
            Else
                pageTemplate.FooterRight.Text = String.Format("Page {0}", pdf.CurrentPage + 1)
            End If

            ' ページの要素を測定します
            pageTemplate.UpdateLayout()
            pageTemplate.Arrange(New Rect(0, 0, rc.Width, rc.Height))

            ' PDFに追加します
            pdf.DrawElement(pageTemplate, rc)
        Next

        ' テンプレート完了
        root.Children.Remove(pageTemplate)
    End Sub
End Class
コードのコピー
Public Class PdfExportOptions
    Public Sub New()
        Margin = New Thickness(96)
        ScaleMode = ScaleMode.PageWidth
        DocumentTitle = "ComponentOne FlexGrid"
    End Sub
    Public Property Margin() As Thickness
        Get
            Return m_Margin
        End Get
        Set(value As Thickness)
            m_Margin = value
        End Set
    End Property
    Private m_Margin As Thickness
    Public Property ScaleMode() As ScaleMode
        Get
            Return m_ScaleMode
        End Get
        Set(value As ScaleMode)
            m_ScaleMode = value
        End Set
    End Property
    Private m_ScaleMode As ScaleMode
    Public Property DocumentTitle() As String
        Get
            Return m_DocumentTitle
        End Get
        Set(value As String)
            m_DocumentTitle = value
        End Set
    End Property
    Private m_DocumentTitle As String
    Public Property KnownPageCount() As Boolean
        Get
            Return m_KnownPageCount
        End Get
        Set(value As Boolean)
            m_KnownPageCount = value
        End Set
    End Property
    Private m_KnownPageCount As Boolean
End Class