【问题标题】:Is there a way to print or transfer the results of a DataGridView in a C# WinForms app?有没有办法在 C# WinForms 应用程序中打印或传输 DataGridView 的结果?
【发布时间】:2019-06-11 22:08:42
【问题描述】:

我创建了一个专门针对我工作的行业的付款计划计算器。我终于得到了所有代码以正确执行并将付款计划安排加载到数据网格中。

我需要数据网格(以及一些其他信息)来物理打印我们的本地打印机、PDF 或至少在另一个表单上重新填充。

这个想法是为了防止我的员工在计算付款安排后不得不在纸上手动填写信息。

一切完成后,数据网格以字符串格式显示每笔付款的日期和金额。

我有 2 个表格。

MainInterface.cs - 在一个“单页应用程序”中完成计算器 这是包含付款计划的数据网格的填充位置 这包含我所有的代码和功能 UI

AutoPay.cs - 我正在尝试打印的“报告”的可视化表示。如果用户单击工具栏上的导出,则会弹出此消息。这里没有任何编码。它只是一个面板、一个 dataGridView 和一些文本框,用于在数据发送到 PDF 或打印机之前添加额外的“自定义”信息(例如:“晚上 7 点运行”)

我的所有代码和功能 UI 现在都在 MainInterface.cs 中。

我采用这种方法是因为我多次未能让 Windows 和 Crystal Report 查看器正常工作。在这一点上,我只是在寻找功能,我几乎准备好告诉他们截取应用程序并打印截图(不理想)。

我想我可能刚刚添加了我的应用实际上并不需要的依赖项和/或库。

我在 MainInterface.cs 中有超过 2000 行代码(我对这一切都很陌生,一旦我开始工作,我就会开始学习类/作用域结构)。

如果相关,这里是 using 语句和命名空间信息:

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PaymentPlanCalculator
{
public partial class paymentPlanCalculator : Form
{ //My entire app (MainInterface.cs is in here)

这是填充数据网格的方式: - 计算日期 - 计算金额 - 付款次数和一些基本的数学算法计算各种情况下的付款

    public void CreateInstallmentDates(int payCycle)
        {
            //int payCycle; // Initialize Integer for PayCycle Days
            int numberOfPayments = Convert.ToInt16(lblTotalPaymentCount.Text); // Set number of payments
            DateTime downPaymentDate = monthCalendarDP.SelectionStart;
            DateTime[] paymentPlanDates = new DateTime[numberOfPayments];
            //DateTime[] paymentPlanDates = new DateTime[numberOfPayments];
            paymentPlanDates[0] = downPaymentDate;

    //This repeats 11 more times, each with 1 'payment' removed
    //This is how the payment dates are calculated:
            if (Convert.ToInt16(lblTotalPaymentCount.Text) == 12)
            {
                DateTime firstInstallmentDate = monthCalendarInstallmentStart.SelectionStart;
                paymentPlanDates[1] = firstInstallmentDate; // 2 Payments
    }
    //...this repeats many more times
            }

显然代码是意大利面条式的

    public void PopulateDataGrid() // THESE ALL NEED THE ADDRESSES TO ADD
        {
            dataGridPPA.Rows.Clear();
            CalculatePaymentDates(); // Call to calculate dates
            int numberOfPayments = Convert.ToInt16(lblTotalPaymentCount.Text);

//With Down Payment and PPA DP and PPA W/ or W/O SIF

if (txtDownPayment.Text != "0.00" && lblInstallmentAmt.Text != "0.00" && sliderRemainingPmtCount.Value > 1) // If PPA has down payment and PPA
            {
                dataGridPPA.Rows.Add(); // Add row
                dataGridPPA["pmtDate", 0].Value = monthCalendarDP.SelectionStart.ToShortDateString(); // Which date is selected (set it to a string)
                dataGridPPA["pmtAmount", 0].Value = String.Format("${0:00}", txtDownPayment.Text); // Take payment amount in Down Payment and add to grid
                // FILL THE INSTALLMENT PAYMENTS
                for (int ppaRow = 1; ppaRow < (numberOfPayments - 1); ppaRow++) // Select second row
                {
                    dataGridPPA.Rows.Add(); // Add row
                    dataGridPPA["pmtDate", ppaRow].Value = PPADates[ppaRow].ToShortDateString(); // Select Date from PPA Dates Array
                    dataGridPPA["pmtAmount", ppaRow].Value = lblInstallmentAmt.Text; // Set installment amount to sting
                }
                // FILL THE FINAL INSTALLMENT PAYMENT
                dataGridPPA.Rows.Add(); // Add final row // Error when not set to schedule - Likely Fixed
                dataGridPPA["pmtDate", numberOfPayments - 1].Value = PPADates[numberOfPayments - 1].ToShortDateString(); // Select Final Date from PPA Date Array
                dataGridPPA["pmtAmount", numberOfPayments - 1].Value = lblRemainder.Text; // Adds remainder amount (after date in previous row)
        }
    }

所有这些代码都能正常工作并完成我需要它做的事情,但正如你所见,它很乱,所以我只需要采取

来自 MainInterface.cs 的 dataGridPPA 并将其复制到 AutoPay.cs

如果这一切都很荒谬,我可能会再试一次“导出报告”方法。我只是找不到任何好的教程,其中的音频质量和口音不会让人无法理解。

我想我遇到了范围问题。如果我尝试这样做:

dataGridPPA = exportPPAdataGrid 

或任何远程相似的迭代,智能感知本质上告诉我,我无法从一个表单读取数据到另一个表单,尽管这两种表单的所有内容都是公开的。

我尝试调用类和命名空间,但没有任何运气。

我已经尝试从 dataGridPPA 创建一个数据源并以这种方式进行传输,显然我在那个方面太过分了。

我愿意做任何可以帮助我将数据传送到正确位置并接受任何建议的事情。越简单越好。

【问题讨论】:

  • 是的,这是可能的。您实际上是在以网格格式打印 data (或应该是)。这里已经有很多关于这个主题的问题。
  • 显然我是在自学。我拥有一家企业,并试图让我的员工的生活稍微轻松一点,因为我找不到任何东西可以做到这一点。我每周工作大约 80 多个小时,并且在过去大约 2 个月内才开始学习 C#。所以我非常愿意接受我在很多事情上都错了的想法。

标签: c# winforms printing datagridview


【解决方案1】:

有几种方法,常见的有:

1) 使用 报告服务器/设计器 - 你说它不适合你。有很多商业解决方案,但它们都需要或多或少要求严格的实施才能使用。当您需要大量不同的打印输出并允许所见即所得的设计时,这是值得的。

2) 编译 HTML(从 datagridview 创建 HTML 表格)并将其显示在 WebBrowser 组件中(来自 .NET 控件的默认集合),您可以从中轻松打印它。对于页面设置等而言,这不是最可靠的方法。可能是最快和最简单的方法,适用于简单的东西。此示例代码打印给定项目的标签:

C#(已转换):

Private void CreateAndShowItemLabel(Int64 ItemID)
{
    String typeText = this.ItemType.GetItemText(this.ItemType.SelectedItem);
    String ContType = Strings.Mid(typeText, 1, typeText.IndexOf(" - ") - 1);
    WebBrowser1.DocumentText = "<HTML><HEADER><STYLE>Table {    border: 1px solid gray; text-indent: 3px; }  #BC {Font = 80px Code39HalfInch; transform: scale(1, 3); }; </STYLE></HEADER><BODY>" + "<TABLE Width=\"400\"> " + "<TR background-color=\"salmon\"><TD Width=\"120\" STYLE=\"font-size:40px\" ROWSPAN=3 align=\"center\">" + ContType + "</TD><TD Width=\"200\" ID=\"BC\" align=\"center\">*" + ItemID.ToString("00000") + "*</TD></TR>" + "<TR background-color=\"salmon\"><TD Width=\"200\" align=\"center\">" + ItemID.ToString("00000") + "</TD></TR>" + "<TR background-color=\"salmon\"><TD Width=\"200\">EUR palet</TD></TR></TABLE></BODY></HTML>";
    WebBrowser2.DocumentText = "<HTML><HEADER><STYLE>Table {    border: 1px solid gray; text-indent: 3px; }  #BC {Font = 60px Code39HalfInch; transform: scale(1, 3); }; </STYLE></HEADER><BODY>" + "<p><img width=\"200\" src=\"file:///G:/Graphics/Epal2.png\" alt=\"EPAL\"></p></BODY></HTML>";
    this.NewID.Text = ItemID.ToString();
    this.BarCode.Text = "*" + ItemID.ToString() + "*";
}

VB.NET:

Private Sub CreateAndShowItemLabel(ItemID As Int64)
    Dim typeText As String = Me.ItemType.GetItemText(Me.ItemType.SelectedItem)
    Dim ContType As String = Mid(typeText, 1, typeText.IndexOf(" - ") - 1)
    WebBrowser1.DocumentText = "<HTML><HEADER><STYLE>Table {    border: 1px solid gray; text-indent: 3px; }  #BC {Font = 80px Code39HalfInch; transform: scale(1, 3); }; </STYLE></HEADER><BODY>" &
                                  "<TABLE Width=""400""> " &
                                  "<TR background-color=""salmon""><TD Width=""120"" STYLE=""font-size:40px"" ROWSPAN=3 align=""center"">" & ContType & "</TD><TD Width=""200"" ID=""BC"" align=""center"">*" & ItemID.ToString("00000") & "*</TD></TR>" &
                                  "<TR background-color=""salmon""><TD Width=""200"" align=""center"">" & ItemID.ToString("00000") & "</TD></TR>" &
                                  "<TR background-color=""salmon""><TD Width=""200"">EUR palet</TD></TR></TABLE></BODY></HTML>"
    WebBrowser2.DocumentText = "<HTML><HEADER><STYLE>Table {    border: 1px solid gray; text-indent: 3px; }  #BC {Font = 60px Code39HalfInch; transform: scale(1, 3); }; </STYLE></HEADER><BODY>" &
                                  "<p><img width=""200"" src=""file:///G:/Graphics/Epal2.png"" alt=""EPAL""></p></BODY></HTML>"
    Me.NewID.Text = ItemID.ToString
    Me.BarCode.Text = "*" & ItemID.ToString & "*"
End Sub

3) 同样,您可以使用 RTF 来完成,但可能会更困难

4) 最专业的方法之一是使用(免费开源)软件,如MigraDoc 并创建可靠的 PDF 文档,您可以将其显示和/或发送到打印机。但是,这肯定不是最快的方法。

【讨论】:

    猜你喜欢
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 2015-07-16
    相关资源
    最近更新 更多