我项目是用vs2017 建的,.NET farmwork 4.7.2
这种报表可以用于任何模式的应用,web,桌面,因为这只是生成一个文件或者文件流
步骤比较详细啰嗦,其中有讲到rdlc怎么新建设计,如果已经会设计rdlc了的可以直接跳到底部看代码的执行结果,
底部还有源码下载链接,百度盘
首先控制台安装报表包
新建rdlc 报表
建立rdlc里要用的数据模型
模型建完,或者修改都要重新生成一下模型所在的dll,这样子在rdlc里才能获取到这个模型
模型建好了,然后就到rdlc设计页面添加数据集
数据集的使用
还可以通过上一个步骤来改变这个表格所绑定的数据集
自定义参数的使用
使用rdlc 内置字段
固定表头操作
注意
我这里用控制台来调用测试
主程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RDLC_Report
{
class Program
{
static void Main(string[] args)
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
List<ReportModel> reports = new List<ReportModel>();
for (int i = 0; i < 1000; i++)
{
reports.Add(new ReportModel { Name = "名字" + i, Age = i, Genner = "性别" + i });
}
stopwatch.Stop();
Console.WriteLine($"模拟数据生成完毕,耗时:{stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
var rdlcPath = $"{AppDomain.CurrentDomain.BaseDirectory}MyFirstReport.rdlc";
var savePath = $"{AppDomain.CurrentDomain.BaseDirectory}File/Image{DateTime.Now.ToString("yyyyMMddHHmmssfff")}";
ReportRDLC reportRDLC = new ReportRDLC(rdlcPath,savePath,ReportRDLC.FileType.Image);
var datasetDic = new Dictionary<string, object>();
//数据集1 “ReportModel”这个名字需要跟在rdlc模板里定义好的名字相同
datasetDic.Add("ReportModel", reports);
//数据集2 “ReportMdoel1”这个名字需要跟在rdlc模板里定义好的名字相同,前面手误打错了单词,也懒得改了
datasetDic.Add("ReportMdoel1", new List<ReportModel1> { new ReportModel1 { Test1 = "测试", Test2 = 111, Test3 = "测试" } });
reportRDLC.DataSources = datasetDic;
//自定义参数列表
var paramList = new List<Microsoft.Reporting.WinForms.ReportParameter>();
paramList.Add(new Microsoft.Reporting.WinForms.ReportParameter("Title", "XXX报表"));//name 要与rdlc模板里定义好的名字一样
reportRDLC.ReportParams = paramList;
//reportRDLC.DeviceInfo = new ReportDeviceInfo { PageHeight = "10cm" };//定义报表页面大小
stopwatch.Stop();
Console.WriteLine($"实例化报表对象完毕,耗时:{stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
//输出初始化类型 Image 文件后缀为tif 图片可翻页
Console.WriteLine(reportRDLC.SaveAsFile());
Console.WriteLine(reportRDLC.RenderOut.MimeType);
stopwatch.Stop();
Console.WriteLine($"生成Image文件完毕,耗时:{stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
//修改类型 输出Excel类型 文件后缀为xls
reportRDLC.SaveType = ReportRDLC.FileType.Excel;
reportRDLC.SavePath = $"{AppDomain.CurrentDomain.BaseDirectory}File/Excel{DateTime.Now.ToString("yyyyMMddHHmmssfff")}";
Console.WriteLine(reportRDLC.SaveAsFile());
Console.WriteLine(reportRDLC.RenderOut.MimeType);
stopwatch.Stop();
Console.WriteLine($"生成Excel文件完毕,耗时:{stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
//修改类型 输出Word类型 文件后缀为doc
reportRDLC.SaveType = ReportRDLC.FileType.Word;
reportRDLC.SavePath = $"{AppDomain.CurrentDomain.BaseDirectory}File/Word{DateTime.Now.ToString("yyyyMMddHHmmssfff")}";
Console.WriteLine(reportRDLC.SaveAsFile());
Console.WriteLine(reportRDLC.RenderOut.MimeType);
stopwatch.Stop();
Console.WriteLine($"生成Word文件完毕,耗时:{stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
//修改类型 输出PDF类型 文件后缀为pdf
reportRDLC.SaveType = ReportRDLC.FileType.PDF;
reportRDLC.SavePath = $"{AppDomain.CurrentDomain.BaseDirectory}File/PDF{DateTime.Now.ToString("yyyyMMddHHmmssfff")}";
Console.WriteLine(reportRDLC.SaveAsFile());
Console.WriteLine(reportRDLC.RenderOut.MimeType);
stopwatch.Stop();
Console.WriteLine($"生成PDF文件完毕,耗时:{stopwatch.ElapsedMilliseconds} ms");
reportRDLC.Dispose();
Console.WriteLine($"完毕");
Console.Read();
}
}
public class ReportModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Genner { get; set; }
}
public class ReportModel1
{
public string Test1 { get; set; }
public int Test2 { get; set; }
public string Test3 { get; set; }
}
}
报表类
挺简单的一个类 代码不多,注释写得很多了
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Install-Package Microsoft.ReportingServices.ReportViewerControl.WinForms -Pre 控制台安装
namespace RDLC_Report
{
public struct ReportRenderOut
{
/// <summary>
/// 警告信息
/// </summary>
public Microsoft.Reporting.WinForms.Warning[] Warnings;
public string[] Streamids;
/// <summary>
/// 文件头类型
/// </summary>
public string MimeType;
/// <summary>
/// 编码格式
/// </summary>
public string Encoding;
/// <summary>
/// 文件后缀名
/// </summary>
public string Extension;
}
/// <summary>
/// 页面打印的宽高,边距(单位 cm\in) 允许为空
/// </summary>
public class ReportDeviceInfo
{
/// <summary>
/// 页面宽度 (单位 cm\in)
/// </summary>
public string PageWidth { get; set; }// = "8.5in";
/// <summary>
/// 页面高度 (单位 cm\in)
/// </summary>
public string PageHeight { get; set; }// = "8.27in";
/// <summary>
/// 左边距 (单位 cm\in)
/// </summary>
public string MarginLeft { get; set; } //= "0.2in";
/// <summary>
/// 右边距 (单位 cm\in)
/// </summary>
public string MarginRight { get; set; }// = "0.2in";
/// <summary>
/// 上边距 (单位 cm\in)
/// </summary>
public string MarginTop { get; set; } //= "0.2in";
/// <summary>
/// 下边距 (单位 cm\in)
/// </summary>
public string MarginBottom { get; set; }// = "0.2in";
}
public class ReportRDLC:IDisposable
{
#region 公共属性
/// <summary>
/// 可生成的文件类型
/// </summary>
public enum FileType { Excel, PDF, Word, Image }
/// <summary>
/// *必填属性 模板的绝对路径 C:\TEST\REPORT.rdlc
/// </summary>
public string RdlcPath { get; set; }
/// <summary>
/// *必填属性 文件生成后的保存路径包括文件名,不需要后缀名(.xxx),后缀名有代码根据SaveType自动匹配(eg:保存成名字为"MYFILE"的文件 C:\TEST\FILE\MYFILE)
/// </summary>
public string SavePath { get; set; }
/// <summary>
/// *必填属性 需要生成的文件类型
/// </summary>
public FileType SaveType { get; set; }
/// <summary>
/// *可选属性,假如你的rdlc模板不需要数据源 数据源 key对应数据集在模板里面的数据集名字,value对应数据列表,一个rdlc允许有多个数据源
/// </summary>
public Dictionary<string, object> DataSources { get; set; }
/// <summary>
/// *可选属性,假如你的rdlc模板不需要自定义参数 报表自定义参数 可以定义字符串 数字 布尔 直接把某个字段传到报表里面使用
/// </summary>
public List<ReportParameter> ReportParams { get; set; }
/// <summary>
/// *可选属性 不设,使用默认 页面大小格式设置
/// </summary>
public ReportDeviceInfo DeviceInfo { get; set; } = new ReportDeviceInfo();
/// <summary>
/// rdlc报表生成字节流时的一些输出参数,执行GetStream(),SaveAsFile()方法后会进行赋值
/// </summary>
public ReportRenderOut RenderOut;
#endregion
public ReportRDLC(string rdlcPath, string savePaht, FileType saveType)
{
RdlcPath = rdlcPath;
SavePath = savePaht;
SaveType = saveType;
}
#region 公共方法
/// <summary>
/// 读取本地rdlc模板,填充数据集和自定义的参数
/// </summary>
/// <returns>LocalReport</returns>
public LocalReport GetLocalReport()
{
LocalReport localReport = new LocalReport();
localReport.EnableExternalImages = true;//设为允许外部资源,不然无法加载图片
//localReport.DataSources.Clear();
localReport.ReportPath = RdlcPath;
if (ReportParams != null) localReport.SetParameters(ReportParams);
//循环将数据集名字和数据源赋给报表主体对象
if (DataSources != null) foreach (var kvp in DataSources) localReport.DataSources.Add(new ReportDataSource(kvp.Key, kvp.Value));
return localReport;
}
/// <summary>
/// 根据SaveType,DeviceInfo,DataSources,ReportParams 返回字节流
/// </summary>
/// <returns></returns>
public byte[] GetStream()
{
LocalReport localReport = GetLocalReport();
try
{
//localReport.Refresh();
string typeName = Enum.GetName(typeof(FileType), SaveType);
string deviceInfo = $@"<DeviceInfo>
<OutputFormat></OutputFormat>
<PageWidth>{DeviceInfo.PageWidth ?? ""}</PageWidth>
<PageHeight>{DeviceInfo.PageHeight ?? ""}</PageHeight>
<MarginTop>{DeviceInfo.MarginTop ?? ""}</MarginTop>
<MarginLeft>{DeviceInfo.MarginLeft ?? ""}</MarginLeft>
<MarginRight>{DeviceInfo.MarginRight ?? ""}</MarginRight>
<MarginBottom>{DeviceInfo.MarginBottom ?? ""}</MarginBottom>
</DeviceInfo>";
//Render方法介绍链接 https://docs.microsoft.com/zh-cn/previous-versions/ms252172(v=vs.140)
//format Excel、PDF、Word 和 Image
byte[] bytes = localReport.Render(typeName, deviceInfo, out RenderOut.MimeType, out RenderOut.Encoding, out RenderOut.Extension, out RenderOut.Streamids, out RenderOut.Warnings);
return bytes;
}
catch(Exception ex)
{
#if DEBUG
throw ex;
#endif
return null;
}
finally
{
localReport.Dispose();
localReport.ReleaseSandboxAppDomain();
//System.GC.Collect();
}
}
/// <summary>
/// 根据SavePath,SaveType生成文件保存到硬盘
/// </summary>
/// <returns>返回保存结果</returns>
public bool SaveAsFile()
{
var stream = GetStream();
if (stream == null || stream.Length == 0) return false;
var file = $"{SavePath}.{RenderOut.Extension}";
var folder = Path.GetDirectoryName(file);
if (!Directory.Exists(folder))//如果文件夹不存在则创建
{
Directory.CreateDirectory(folder);
}
using (FileStream fs = new FileStream(file, FileMode.Create))
{
fs.Write(stream, 0, stream.Length);
fs.Close();
}
return true;
}
#endregion
public static string GetMd5(string md5string)
{
byte[] testEncrypt = System.Text.Encoding.UTF8.GetBytes(md5string);
//获取加密服务
System.Security.Cryptography.MD5CryptoServiceProvider md5CSP = new System.Security.Cryptography.MD5CryptoServiceProvider();
//加密Byte[]数组
byte[] resultEncrypt = md5CSP.ComputeHash(testEncrypt);
StringBuilder sub = new StringBuilder();
for (int i = 0; i < resultEncrypt.Length; i++)
{
sub.Append(resultEncrypt[i].ToString("x2"));
}
return sub.ToString().ToUpper();
}
public void Dispose()
{
DataSources = null;
ReportParams = null;
}
}
}
结果
PDF.
Excel.
图片.
word.
源码下载地址 百度盘
链接: https://pan.baidu.com/s/1P52swF0u1RUq2m4nP1W1YA 提取码: a1fd