【问题标题】:How to print C# chart with more pages如何打印具有更多页面的 C# 图表
【发布时间】:2020-06-21 05:24:45
【问题描述】:

我已经完成了 C# 项目,但是当出现更多页面的数据点时,我在打印它的图表时遇到了问题,当我开始获取更多页面时,我得到了滚动条的工作,因此用户可以查看所有页面上的所有数据,但我找不到如何使打印预览显示或打印它们, 当点击打印时,它只显示打印预览的第一页,打印出来的时候也是一样的。

她是打印代码:

     PrintPreviewDialog ppd = new PrintPreviewDialog();

     ppd.Document = this.chart1.Printing.PrintDocument;

     ((Form)ppd).WindowState = FormWindowState.Maximized;

     chart1.Printing.PrintDocument.DefaultPageSettings.Landscape = true;

     
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Left = 0;
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Right = 0;
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Top = 0;
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Bottom = 0;

     
     ppd.ShowDialog();

这是图表加载代码:

    public void loadChart(string sqlvalue)//load chart method
     {
     
     chart1.ChartAreas[0].AxisY.Maximum = 55;
     chart1.ChartAreas[0].AxisY.Minimum = 35;
     chart1.ChartAreas[0].AxisY.Interval = 5;//control how many lines/Interval 


     chart1.ChartAreas[0].AxisY.ScrollBar.Enabled = true;
     chart1.ChartAreas[0].AxisY.ScaleView.Zoomable = true;

     chart1.ChartAreas[0].AxisX.Minimum = 0;
    // chart1.ChartAreas[0].AxisX.Maximum = 10;
     chart1.ChartAreas[0].AxisX.Interval = 1;

     //X AXES label angle
     chart1.ChartAreas[0].AxisX.LabelStyle.Angle = 60;
         
     da = new SqlDataAdapter(sqlvalue, cn.connect());

     da.Fill(dt);

     this.chart1.DataSource = dt;
     this.chart1.Series["left"].XValueMember = dt.Columns[3].ToString();//date data
     this.chart1.Series["left"].YValueMembers = dt.Columns[1].ToString();//spindle 1 data
     this.chart1.Series["Right"].YValueMembers = dt.Columns[2].ToString();//spindle 2 data

     //label the series lines, Backcolor and forcolor
     chart1.Series[0].LabelBackColor = Color.Red;
     chart1.Series[0].LabelForeColor = Color.White;



     //datapoint marker's color, bordercolor,style and size
     chart1.Series[0].MarkerColor = Color.White;
     chart1.Series[0].MarkerBorderColor = Color.Black;
     chart1.Series[0].MarkerStyle = MarkerStyle.Circle;
     chart1.Series[0].MarkerSize = 8;

     //datapoint marker's color, style and size
     chart1.Series[1].MarkerColor = Color.White;
     chart1.Series[1].MarkerBorderColor = Color.Black;
     chart1.Series[1].MarkerStyle = MarkerStyle.Circle;
     chart1.Series[1].MarkerSize = 8;

     
     chart1.Series[1].LabelBackColor = Color.Blue;
     chart1.Series[1].LabelForeColor = Color.White;

    
     //Chart background lines color
     chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Silver;
     chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Silver;

    

     this.chart1.DataBind();
     cn.disconnect();
  
     // enable autoscroll
     chart1.ChartAreas[0].CursorX.AutoScroll = true;//------------
     chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
     chart1.ChartAreas[0].AxisX.ScaleView.Zoom(0, 15);

     
      
     chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;

     // set scrollbar small change to the target size
     chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = 15;


     Legend left = new Legend();
     Legend LC = CustomCloneLegend(chart1, left);
     chart1.Legends.Add(LC);

  
     chart1.Padding = Padding.Empty;

     ChartArea CA = chart1.ChartAreas[0];
     CA.Position = new ElementPosition(4,6, 100, 90);
    
    }
    

感谢您的时间和帮助,这里是图表代码更新:

 private static Image MergeImages(List<Image> imageList)
  {
     var finalSize = new Size();
     foreach (var image in imageList)
     {
        if (image.Width > finalSize.Width)
        {
           finalSize.Width = image.Width;
        }
        finalSize.Height += image.Height;
     }
     var outputImage = new Bitmap(finalSize.Width, finalSize.Height);
     using (var gfx = Graphics.FromImage(outputImage))
     {
        var y = 0;
        foreach (var image in imageList)
        {
           gfx.DrawImage(image, 0, y);
           y += image.Height;
        }
     }
     return outputImage;
  }

第二种方法:

 List<Image> ChartsToImages(List<Chart> charts)
  {
     var imageList = new List<Image>();
     foreach (var c in charts)
     {
        using (var ms = new MemoryStream())
        {
           c.SaveImage(ms, ChartImageFormat.Png);
           var bmp = System.Drawing.Bitmap.FromStream(ms);
           imageList.Add(bmp);
        }
     }
     return imageList;
  }

还有这段代码

     var chartList = new List<Chart> { chart1 };
     var imageList = ChartsToImages(chartList);
     var finalImage = MergeImages(imageList);
     finalImage.Save("D:\\Junk.png", ImageFormat.Png);

我不确定你的第一条评论是什么意思,但我在将图表转换为图像问题下找到了这段代码。此代码将图表转换并保存在相同数量的页面中,但我需要在 printpreviewcontrol 中显示它们并打印它们。

【问题讨论】:

  • 您可能需要选择几条路线。一种是创建图表的大(宽)图像并分段打印。请注意,您可以创建比屏幕上显示的大得多的位图。 40k像素宽度没问题;只需设置大小并使用chart.SaveImage .. 这很简单,但缺点是y 轴或图例等所有侧面信息只会显示在第一节和最后一节..
  • 另一种选择是只显示部分数据,并在捕获数据后转到下一部分。您可以使用滚动条,它在打印输出上不太好,或者设置 X 轴的最小值和最大值..
  • 还有内置的打印管理器,但我认为它不适用于多页图表。但是,它应该可以与上面的 Min/Max 滚动一起使用。即,移动 x 轴最小值和最大值。 Example
  • 我刚刚做了一个快速测试,有了这个ChartArea ca = chart.ChartAreas[0]; Axis ax = ca.AxisX; double min = ax.Minimum; double max = ax.Maximum; int pages = 4; double pagerange = (max - min) / pages; for (int i = 0; i &lt; pages; i++) { ax.Minimum = min + pagerange * i; ax.Maximum = ax.Minimum + pagerange; // do the prinint stuff here! },可以轻松地将图表打印到 n 页上。要真正“进行打印”,您需要决定是否希望每页有一个图表部分,是否要将图表部分打印到您控制的页面上。对于前者...
  • ...为后者使用 ..chart.Printing.Print 将循环集成到您的打印例程中,并使用 chart.Printing.PrintPaint 及其 Graphics 对象..!如果您想保存页面,请使用图像中的 Graphics 对象。矩形可让您将图表放置在您想要的位置和大小

标签: c#


【解决方案1】:

以下代码是指按页数计算起点和终点的打印。并且网格视图值字符是基于行循环的页面计数。

    private int numberOfItemsPerPage = 0;
    private int numberOfItemsPrintedSoFar = 0;

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
       
                  

        int height = 480; //page height stating point
        for (int l = numberOfItemsPrintedSoFar; l < dataGridView2.Rows.Count; l++)
        {
            numberOfItemsPerPage = numberOfItemsPerPage + 1;
            if (numberOfItemsPerPage <= 25) // 25 is Page Line Item
            {
                numberOfItemsPrintedSoFar++;

                if (numberOfItemsPrintedSoFar <= dataGridView2.Rows.Count)
                {
                    
                    height += dataGridView2.Rows[0].Height;
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[0].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(5, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[1].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(170, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[2].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(290, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[3].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(345, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                }
                else
                {
                    e.HasMorePages = false;
                }

            }
            else
            {
                numberOfItemsPerPage = 0;
                e.HasMorePages = true;
                return;

            }


        }
        numberOfItemsPerPage = 0;
        numberOfItemsPrintedSoFar = 0;

    }



    

【讨论】:

  • 虽然这确实显示了多页打印的基本示例,但我看不出它如何回答关于图表的问题。但是在创建要打印的部分图像之后,它可能会被使用..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多