此文出现MVC,就是网页上调用winform打印控件PrintPreviewDialog,好诡异,出线了!
好了,开始。。。。 首先你要做一个报表:RDLC (微软的东东) 当然这个微软的RDLC需要配置一个数据源xsd(不用链接数据库,我这就是手动在数据源里面创建个table对象而已), 然后需要一个aspx页面来显示这个报表 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TongJi.aspx.cs" Inherits="Jaya.Web.Reports.TongJi" ValidateRequest="false" %>
<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:DropDownList ID="DropDownList1" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Value="100" Text="100"></asp:ListItem>
<asp:ListItem Value="80" Text="80"></asp:ListItem>
<asp:ListItem Value="50" Text="50"></asp:ListItem>
<asp:ListItem Value="30" Text="30"></asp:ListItem>
</asp:DropDownList>
<div id="mainPanel" style=" overflow-x: hidden; height: 680px; border-left: 1px solid scrollbar;">
<asp:Button ID="Button13" runat="server" Text="打印" OnClick="Button2_Click" />
<asp:Button ID="Button1" runat="server" Text="刷新" OnClick="Button7_Click" />
<asp:Button ID="Button2" runat="server" Text="首页" OnClick="Button8_Click" />
<asp:Button ID="Button3" runat="server" Text="上一页" OnClick="Button9_Click" />
<asp:Button ID="Button4" runat="server" Text="下一页" OnClick="Button10_Click" />
<asp:Button ID="Button5" runat="server" Text="尾页" OnClick="Button11_Click" />
<asp:Button ID="Button6" runat="server" Text="导出EXCEL" OnClick="Button5_Click" />
<asp:Button ID="Button7" runat="server" Text="导出图片" OnClick="Button4_Click" />
<asp:Button ID="Button8" runat="server" Text="导出PDF" OnClick="Button3_Click" />
<asp:Button ID="Button9" runat="server" Text="导出WORD" OnClick="Button6_Click" />
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana" Font-Size="8pt" WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt" Width="680px" Height="670px">
<LocalReport ReportPath="Reports
ep_examroom.rdlc">
</LocalReport>
</rsweb:ReportViewer>
</div>
</form>
</body>
</html>
-----------------------华丽的分割线 上面是前台代码 下面是后台代码------------------------ public enum FileType
{
PDF = 0,
Image = 1,
Excel = 2,
Word = 3
}
public partial class TongJi : System.Web.UI.Page
{
DataTable dt1 = null;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string rpath;
Hashtable ht = new Hashtable();
DataTable dt = GetData(out rpath, ref ht);
ReportDataSource rds = new ReportDataSource("DataSet1", dt);//真数据源
ReportViewer1.LocalReport.DataSources.Clear();
ReportViewer1.LocalReport.DataSources.Add(rds);
List<ReportParameter> rps = new List<ReportParameter>();
foreach (var item in ht.Keys)//自定义报表需要的参数
{
ReportParameter rp1 = new ReportParameter(item.ToString(), ht[item].ToString());
rps.Add(rp1);
}
//ReportParameter rp1 = new ReportParameter("kskm", "123");
//ReportParameter rp2 = new ReportParameter("rq", "123");
ReportViewer1.LocalReport.SetParameters(rps.ToArray());
ReportViewer1.LocalReport.ReportPath = "Reports\" + rpath + ".rdlc";//rep_examroom
ReportViewer1.LocalReport.Refresh();
ReportViewer1.DataBind();
}
}
private DataTable GetData(out string rpath, ref Hashtable ht)
{
string jsondata = Request["jsondata"];//必传数据json
rpath = Request["rpath"];//必传数据报表路径
foreach (string key in Request.QueryString.AllKeys)//自定义参数
{
if (key != "rpath" && key != "jsondata")
{
ht.Add(key, Request[key].ToString());
}
}
DataTable dt = Common.CuryHelp.JsonToDataTable(jsondata);//json字符串转换DataTable对象
return dt;
}
/// <summary>
/// 打印
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button2_Click(object sender, EventArgs e)
{
string rpath;
Hashtable ht = new Hashtable();
DataTable dt2 = GetData(out rpath, ref ht);
new PrintHelp().Run(AppDomain.CurrentDomain.BaseDirectory + "\Reports\" + rpath + ".rdlc", dt2, "DataSet1", ht);
}
/// <summary>
/// 刷新
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button7_Click(object sender, EventArgs e)
{
this.ReportViewer1.LocalReport.Refresh();
}
/// <summary>
/// 首页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button8_Click(object sender, EventArgs e)
{
this.ReportViewer1.CurrentPage = 1;
}
/// <summary>
/// 上一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button9_Click(object sender, EventArgs e)
{
if (this.ReportViewer1.CurrentPage != 1)
{
this.ReportViewer1.CurrentPage--;
}
}
/// <summary>
/// 下一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button10_Click(object sender, EventArgs e)
{
if (this.ReportViewer1.CurrentPage != this.ReportViewer1.LocalReport.GetTotalPages())
{
this.ReportViewer1.CurrentPage++;
}
}
/// <summary>
/// 尾页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button11_Click(object sender, EventArgs e)
{
this.ReportViewer1.CurrentPage = this.ReportViewer1.LocalReport.GetTotalPages();
}
/// <summary>
/// 缩放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
this.ReportViewer1.ZoomMode = ZoomMode.Percent;
this.ReportViewer1.ZoomPercent = Convert.ToInt32(this.DropDownList1.SelectedValue);
}
protected void Button3_Click(object sender, EventArgs e)
{
ExportFile(FileType.PDF, "out.pdf");
}
protected void Button4_Click(object sender, EventArgs e)
{
ExportFile(FileType.Image, "out.jpeg");//这里可以使用任意的图片格式 只要修改out.jpeg为其他格式的名字就可以了
}
protected void Button5_Click(object sender, EventArgs e)
{
ExportFile(FileType.Excel, "out.xls");
}
protected void Button6_Click(object sender, EventArgs e)
{
ExportFile(FileType.Word, "out.doc");
}
#region 导出文件
private void ExportFile(FileType ft, string filename)
{
CreateFile(ft, filename);
string strPath = Server.MapPath(filename);
DownloadFile(strPath, filename);
}
private void CreateFile(FileType ft, string filename)
{
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding = "utf-8";
string extension;
byte[] bytes = this.ReportViewer1.LocalReport.Render(ft.ToString(), null, out mimeType,
out encoding, out extension, out streamids, out warnings);
FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(filename), FileMode.Create);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
fs.Dispose();
}
public void DownloadFile(string path, string name)
{
try
{
System.IO.FileInfo file = new System.IO.FileInfo(path);
Response.Clear();
Response.Charset = "utf-8";
Response.ContentEncoding = System.Text.Encoding.UTF8;
// 添加头信息,为"文件下载/另存为"对话框指定默认文件名
Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(name));
// 添加头信息,指定文件大小,让浏览器能够显示下载进度
Response.AddHeader("Content-Length", file.Length.ToString());
// 指定返回的是一个不能被客户端读取的流,必须被下载
Response.ContentType = "application/octet-stream";
// 把文件流发送到客户端
Response.WriteFile(file.FullName);
// 停止页面的执行
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (Exception ex)
{
Response.Write("<script>alert('系统出现以下错误://n" + ex.Message + "!//n请尽快与管理员联系.')</script>");
}
}
#endregion
} -----------------------------------------------是不是有点多,没关系 无脑复制即可 有错就删掉它!---------- 需要一个帮助类 已经封装好 (当然你也可以根据自己需要修改扩展): /// <summary>
/// PrintHelp 的摘要描述
/// </summary>
public class PrintHelp
{
private int m_currentPageIndex;
private IList<Stream> m_streams;
/// <summary>
///
/// </summary>
/// <param name="reportPath">報表路徑</param>
/// <param name="printerName">打印機名稱(使用默認打印機,不賦值)</param>
/// <param name="dt1">報表數據源1</param>
/// <param name="dt1SourceName">報表中數據源1對應名稱</param>
/// <param name="dt2">報表數據源2</param>
/// <param name="dt2SourceName">報表中數據源2對應名稱</param>
public void Run(string reportPath, string printerName, DataTable dt1, string dt1SourceName, DataTable dt2, string dt2SourceName, bool isHindeLogo)
{
LocalReport report = new LocalReport();
report.ReportPath = reportPath;//加上报表的路径
report.DataSources.Add(new ReportDataSource(dt1SourceName, dt1));
report.DataSources.Add(new ReportDataSource(dt2SourceName, dt2));
report.EnableExternalImages = true;
ReportParameter rp = new ReportParameter("isHindeLogoImg", isHindeLogo.ToString());//这里我在报表里弄的参数
report.SetParameters(rp);
Export(report);
m_currentPageIndex = 0;
Print(printerName);
}
//我用的是下面这个方法 方法按自己的需要去修改封装 public void Run(string reportPath, DataTable dt1, string dt1SourceName,Hashtable ht )
{
LocalReport report = new LocalReport();
report.ReportPath = reportPath;//加上报表的路径
report.DataSources.Add(new ReportDataSource(dt1SourceName, dt1));
report.EnableExternalImages = true;
List<ReportParameter> rps = new List<ReportParameter>();
foreach (var item in ht.Keys)
{
ReportParameter rp1 = new ReportParameter(item.ToString(), ht[item].ToString());
rps.Add(rp1);
}
report.SetParameters(rps);
Export(report);
m_currentPageIndex = 0;
Print("");
}
private void Export(LocalReport report)
{
string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>EMF</OutputFormat>" +
" <PageWidth>210mm</PageWidth>" +
" <PageHeight>297mm</PageHeight>" +
" <MarginTop>5mm</MarginTop>" +
" <MarginLeft>10mm</MarginLeft>" +
" <MarginRight>10mm</MarginRight>" +
" <MarginBottom>5mm</MarginBottom>" +
"</DeviceInfo>";//这里是设置打印的格式 边距什么的
Warning[] warnings;
m_streams = new List<Stream>();
try
{
report.Render("Image", deviceInfo, CreateStream, out warnings);//一般情况这里会出错的 使用catch得到错误原因 一般都是简单错误
}
catch (Exception ex)
{
Exception innerEx = ex.InnerException;//取内异常。因为内异常的信息才有用,才能排除问题。
while (innerEx != null)
{
//MessageBox.Show(innerEx.Message);
string errmessage = innerEx.Message;
innerEx = innerEx.InnerException;
}
}
foreach (Stream stream in m_streams)
{
stream.Position = 0;
}
}
private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
{
//name 需要进一步处理
Stream stream = new FileStream(name + DateTime.Now.Millisecond + "." + fileNameExtension, FileMode.Create);//为文件名加上时间
m_streams.Add(stream);
return stream;
}
private void Print(string printerName)
{
//string printerName = this.TextBox1.Text.Trim();// "傳送至 OneNote 2007";
if (m_streams == null || m_streams.Count == 0)
return;
PrintDocument printDoc = new PrintDocument();
// string aa = printDoc.PrinterSettings.PrinterName;
if (printerName.Length > 0)
{
printDoc.PrinterSettings.PrinterName = printerName;
}
foreach (PaperSize ps in printDoc.PrinterSettings.PaperSizes)
{
if (ps.PaperName == "A4")
{
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = ps;
printDoc.DefaultPageSettings.PaperSize = ps;
// printDoc.PrinterSettings.IsDefaultPrinter;//知道是否是预设定的打印机
}
}
if (!printDoc.PrinterSettings.IsValid)
{
string msg = String.Format("Can't find printer " + printerName);
System.Diagnostics.Debug.WriteLine(msg);
return;
}
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
PrintPreview(printDoc);//这个地方测试打印预览 这个地方很诡异 他会在网页上弹出winform 有木有? 当然这个窗口在网页后面,需要alt+tab切一下看到啦(藏得深,怕你找不到)。。。。
//printDoc.Print();//这地方是直接打印 放开注释就是直接去打印机打印啦
}
//下面是测试用的三种打印预览 都是winform控件哦
private void RuntimeDialog(PrintDocument pDoc)
{
PrintPreviewDialog pPDlg;
pPDlg = new PrintPreviewDialog();
pPDlg.Document = pDoc;
pPDlg.WindowState = FormWindowState.Normal;//设置窗口
pPDlg.PrintPreviewControl.Zoom = 1.0;//设置百分比大小
pPDlg.PrintPreviewControl.Columns = 1;
pPDlg.ShowDialog();
//pPDlg.Dispose();
}
private void PrintPreviewControl(PrintDocument pDoc)
{
Form formPreview = new Form();
PrintPreviewControl previewControl = new PrintPreviewControl();
previewControl.Document = pDoc;
previewControl.StartPage = 1;
formPreview.WindowState = FormWindowState.Normal;
formPreview.Controls.Add(previewControl);
formPreview.Controls[0].Dock = DockStyle.Fill;
formPreview.ShowDialog();
//formPreview.Dispose();
}
private void PrintPreview(PrintDocument pDoc)
{
PrintPreviewDialog pPDlg;
pPDlg = new PrintPreviewDialog();
PrintPreviewControl previewControl = new PrintPreviewControl();
//设置页面的预览的页码
//设置显示页面显示的大小(也就是原页面的倍数)
pPDlg.PrintPreviewControl.StartPage = 0;
pPDlg.PrintPreviewControl.Zoom = 1.0;
//设置或返回窗口状态,即该窗口是最小化、正常大小还是其他状态。
pPDlg.WindowState = FormWindowState.Maximized;
//设置和获取需要预览的文档
//将窗体显示为指定者的模式对话框
pPDlg.Document = pDoc;
pPDlg.ShowDialog();
}
private void PrintPage(object sender, PrintPageEventArgs ev)
{
Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
ev.Graphics.DrawImage(pageImage, 0, 0, 827, 1169);//設置打印尺寸 单位是像素
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}
======================好了 下面开始MVC部分 需要一个视图 然后写一个ajax 去后台获取数据(相信这部分都会把) 然后拿到数据后 用js拼接一个iframe把上面的那个aspx页面嵌套到你的mvc页面中来,具体可以参考下面代码(其中用到了json字符串地址栏传输,到那边可以用一个方法把json字符串转换城DataTable),下面提供转换代码。注意我封装后的传参(可以修改自己需要的,下面代码仅供参考,无脑复制肯定不行的) 有几个重要参数:rpath是调用的报表文件名称,jsondata是需要传送的数据(可以理解为真数据源),其它都是自定义参数,按照你报表上需要的参数自己设置。 (至于后台如何把数据转换json传到前台,别的日志里面有,至于前台怎么把json对象转换成json字符串,请使用JSON2.js) function chaxun() {
var _cd1 = $('#d1').val();
var _cd2 = $('#d2').val();
if (_cd1 != "" && _cd2 != "") {
$.post('/Drv_statistics/TJ_ExamRoomPost', { kskm: $('#_km').val(), d1: _cd1, d2: _cd2 }, function (data) {
//接收参数
var _d1 = data.Date1;
var _d2 = data.Date2;
//组织报表需要变量
var _km = data.KM;
var _rq = _d1 + " 至 " + _d2;
//要使用的报表名称
var _rpath = "rep_examroom";
//报表要使用的数据
var str_json = JSON.stringify(data.JData);
var strhtml = "<iframe width='700' height='650' id='' src='/Reports/TongJi.aspx?rpath=" + _rpath + "&kskm=" + _km + "&rq=" + _rq + "&jsondata=" + str_json + "' frameborder='no' border='0' marginwidth='0' marginheight='0' scrolling='no' allowtransparency='yes' style='overflow:hidden;height:700px'></iframe>";
$('#_ifmdiv').html(strhtml);
})
}
} ==================================== json to DataTable /// <summary>
/// 将json转换为DataTable
/// </summary>
/// <param name="strJson">得到的json</param>
/// <returns></returns>
public static DataTable JsonToDataTable(string strJson)
{
//转换json格式
strJson = strJson.Replace(","", "*"").Replace("":", ""#").ToString();
//取出表名
var rg = new Regex(@"(?<={)[^:]+(?=:[)", RegexOptions.IgnoreCase);
string strName = rg.Match(strJson).Value;
DataTable tb = null;
//去除表名
strJson = strJson.Substring(strJson.IndexOf("[") + 1);
strJson = strJson.Substring(0, strJson.IndexOf("]"));
//获取数据
rg = new Regex(@"(?<={)[^}]+(?=})");
MatchCollection mc = rg.Matches(strJson);
for (int i = 0; i < mc.Count; i++)
{
string strRow = mc[i].Value;
string[] strRows = strRow.Split('*');
//创建表
if (tb == null)
{
tb = new DataTable();
tb.TableName = strName;
foreach (string str in strRows)
{
var dc = new DataColumn();
string[] strCell = str.Split('#');
if (strCell[0].Substring(0, 1) == """)
{
int a = strCell[0].Length;
dc.ColumnName = strCell[0].Substring(1, a - 2);
}
else
{
dc.ColumnName = strCell[0];
}
tb.Columns.Add(dc);
}
tb.AcceptChanges();
}
//增加内容
DataRow dr = tb.NewRow();
for (int r = 0; r < strRows.Length; r++)
{
dr[r] = strRows[r].Split('#')[1].Trim().Replace(",", ",").Replace(":", ":").Replace(""", "");
}
tb.Rows.Add(dr);
tb.AcceptChanges();
}
return tb;
}================================ 效果图。。 |