C# 通过对象和ExportToStream填充Crystal报表数据源

C# 通过对象和ExportToStream填充Crystal报表数据源,c#,sql-server,asp.net-mvc,pdf,crystal-reports,C#,Sql Server,Asp.net Mvc,Pdf,Crystal Reports,我使用的是VS 2015,Crystal Report也是最新的,SQL Server 2012 我想通过viewmodel类填充Crystal Report数据源并将其导出为PDF ReportDocument rptH = new ReportDocument(); rptH.FileName = Server.MapPath("~/reports/InvoiceReportsSample1.rpt"); var showInvoices = (from

我使用的是VS 2015,Crystal Report也是最新的,SQL Server 2012

我想通过viewmodel类填充Crystal Report数据源并将其导出为PDF

 ReportDocument rptH = new ReportDocument();
 rptH.FileName = Server.MapPath("~/reports/InvoiceReportsSample1.rpt");

 var showInvoices =
               (from ids in context.Invoices
                where ids.InvoiceNumber == "01-04-2017-1"
                select new Invoice_Report_ViewModel()
                {
                    Invoiceid = ids.Invoiceid,
                    InvoiceNumber = ids.InvoiceNumber,
                    CustomerCompanyName = ids.CustomerCompanyName,
                    FirstBlankSpaceForPanel1 = ids.FirstBlankSpaceForPanel1,
                    MainDiscount = ids.MainDiscount,
                    MainTaxes = ids.MainTaxes,
                    MainTotal = ids.MainTotal,
                    TypeOfPortals = ids.TypeOfPortals,
                    TypeOfTickets = ids.TypeOfTickets,
                    SecondBlankSpaceForPanel2 = ids.SecondBlankSpaceForPanel2,
                }).First();

        var showInvoiceDetails = (from ids in context.InvoiceDetailses
                                  where
                                      ids.Invoiceid == showInvoices.Invoiceid
                                  select new InvoiceDetails_Report_ViewModel()
                                  {

                                  }).ToList();
       var querylist = new List<Invoice_Report_ViewModel> { showInvoices };
        rptH.Database.Tables[0].SetDataSource(querylist);
        rptH.Database.Tables[0].SetDataSource(showInvoiceDetails);
        rptH.Refresh();           
        Stream stream = rptH.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
        return File(stream, "application/pdf"); 
ReportDocument rptH=新的ReportDocument();
rptH.FileName=Server.MapPath(“~/reports/InvoiceReportsSample1.rpt”);
var显示发票=
(来自上下文中的ID。发票)
其中id.InvoiceNumber==“01-04-2017-1”
选择新发票\报告\视图模型()
{
Invoiceid=ids.Invoiceid,
InvoiceNumber=ids.InvoiceNumber,
CustomerCompanyName=ids.CustomerCompanyName,
FirstBlankSpaceForPanel1=ids.FirstBlankSpaceForPanel1,
mainplose=ids.mainplose,
MainTaxes=id.MainTaxes,
MainTotal=ids.MainTotal,
TypeOfPortals=ids.TypeOfPortals,
TypeOfTickets=ids.TypeOfTickets,
SecondBlankSpaceForPanel2=ids.SecondBlankSpaceForPanel2,
}).First();
var showInvoiceDetails=(来自context.invoiceDetails中的ID
哪里
ids.Invoiceid==showInvoices.Invoiceid
选择新发票详细信息\报告\视图模型()
{
}).ToList();
var querylist=新列表{showInvoices};
rptH.Database.Tables[0].SetDataSource(querylist);
rptH.Database.Tables[0].SetDataSource(showInvoiceDetails);
rptH.Refresh();
Stream=rptH.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
返回文件(流,“应用程序/pdf”);
请帮我找出一个错误

数据源登录失败

但我并没有将报表连接到数据库,而且我还使用.NET对象配置了报表


请帮助

我假设您正在尝试设置两个数据源。 您需要将它们设置为相关的datatable。 你可以试试下面的方法

 rptH.Database.Tables[0].SetDataSource(querylist);
 rptH.Database.Tables[1].SetDataSource(showInvoiceDetails);

我假设您正在尝试设置两个数据源。 您需要将它们设置为相关的datatable。 你可以试试下面的方法

 rptH.Database.Tables[0].SetDataSource(querylist);
 rptH.Database.Tables[1].SetDataSource(showInvoiceDetails);

我遇到了这个错误, 首先,您需要创建一个自定义DataTable,其中包含不同表中的字段

然后您需要添加此代码 .todata来自ReportHelper

    //domResult -> List of your View Model
     DataTable dt = ReportHelper.ToDataTable(domResult);
    // LCDraft_Domestic--> Crystal Report
     LCDraft_Domestic rpt = new LCDraft_Domestic();
   //My Data Table
      rpt.Database.Tables["DraftData"].SetDataSource(dt);
为了避免crystal report引发的系统可空错误,您需要将列表查询转换为DataTable

创建静态类名ReportHelper

 public static class ReportHelper
{



    public static DataTable ToDataTable<T>(this IList<T> items)
    {
        var tb = new DataTable(typeof(T).Name);

        PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo prop in props)
        {
            Type t = GetCoreType(prop.PropertyType);
            tb.Columns.Add(prop.Name, t);
        }

        foreach (T item in items)
        {
            var values = new object[props.Length];

            for (int i = 0; i < props.Length; i++)
            {
                values[i] = props[i].GetValue(item, null);
            }

            tb.Rows.Add(values);
        }

        return tb;
    }

    /// <summary>
    /// Determine of specified type is nullable
    /// </summary>
    public static bool IsNullable(Type type)
    {
        return !type.IsValueType || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>));
    }

    /// <summary>
    /// Return underlying type if type is Nullable otherwise return the type
    /// </summary>
    public static Type GetCoreType(Type type)
    {
        if (type != null && IsNullable(type))
        {
            if (!type.IsValueType)
            {
                return type;
            }
            else
            {
                return Nullable.GetUnderlyingType(type);
            }
        }
        else
        {
            return type;
        }
    }
    static TableLogOnInfo crTableLogonInfo;
    static ConnectionInfo crConnectionInfo;
    static Tables crTables;
    static Database crDatabase;

    public static void ReportLogin(ReportDocument crDoc, string Server, string Database, string UserID, string Password)
    {
        crConnectionInfo = new ConnectionInfo();
        crConnectionInfo.ServerName = Server;
        crConnectionInfo.DatabaseName = Database;
        crConnectionInfo.UserID = UserID;
        crConnectionInfo.Password = Password;
        crDatabase = crDoc.Database;
        crTables = crDatabase.Tables;
        foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in crTables)
        {
            crTableLogonInfo = crTable.LogOnInfo;
            crTableLogonInfo.ConnectionInfo = crConnectionInfo;
            crTable.ApplyLogOnInfo(crTableLogonInfo);
        }
    }
    //No Login
    public static void ReportLogin(ReportDocument crDoc, string Server, string Database)
    {
        crConnectionInfo = new ConnectionInfo();
        crConnectionInfo.ServerName = Server;
        crConnectionInfo.DatabaseName = Database;
        crConnectionInfo.IntegratedSecurity = true;
        crDatabase = crDoc.Database;
        crTables = crDatabase.Tables;
        foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in crTables)
        {
            crTableLogonInfo = crTable.LogOnInfo;
            crTableLogonInfo.ConnectionInfo = crConnectionInfo;
            crTable.ApplyLogOnInfo(crTableLogonInfo);
        }
    }

}
公共静态类ReportHelper
{
公共静态数据表ToDataTable(此IList项)
{
var tb=新数据表(typeof(T).Name);
PropertyInfo[]props=typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach(PropertyInfo props in props)
{
类型t=GetCoreType(prop.PropertyType);
tb.Columns.Add(道具名称,t);
}
foreach(项目中的T项目)
{
var值=新对象[props.Length];
for(int i=0;i
我遇到了这个错误, 首先,您需要创建一个自定义DataTable,其中包含不同表中的字段

然后您需要添加此代码 .todata来自ReportHelper

    //domResult -> List of your View Model
     DataTable dt = ReportHelper.ToDataTable(domResult);
    // LCDraft_Domestic--> Crystal Report
     LCDraft_Domestic rpt = new LCDraft_Domestic();
   //My Data Table
      rpt.Database.Tables["DraftData"].SetDataSource(dt);
为了避免crystal report引发的系统可为null的错误,您需要