--最近有个客户提出来界面的数据不够准确,于是进行查证,发现打印界面全部使用的是HTML做出来的.于是参考一下这也是一种打印形式.
--如下图为打印图
--相关程序代码如下
private void CreateHtml(DataSet data)
{
StringBuilder sb = new StringBuilder();
sb.Append("<html><head><title>客户合同对账单</title>");
sb.Append("<style type='text/css'>");
sb.Append("table {");
sb.Append("border-collapse:collapse;");
sb.Append("border:solid #999;");
sb.Append("border-width:1px 0 0 1px;}");
sb.Append("table th,table td {border:solid #999;border-width:0 1px 1px 0;padding:2px;}");
sb.Append("tfoot td {text-align:center;}");
sb.Append("</style>");
sb.Append("</head>");
sb.Append("<body>");
sb.Append("<table width='90%' border='1' align='center'>");
sb.Append(string.Format("<tr><td colspan = '10' align='center'>{0}</td></tr>", "客 户 合 同 对 账 单"));
int cntTable = data.Tables.Count;
decimal PlanAmount = 0, RealAmount = 0;
decimal PlanAmountDetail = 0, RealAmountDetail = 0;
decimal BalanceAmount = 0;
if (cntTable > 0)
{
DataTable dtHead = data.Tables[0];
foreach (DataRow dr in dtHead.Rows)
{
sb.Append("<tr>");
sb.Append(string.Format("<td>{0}</td>", " "));
sb.Append(string.Format("<td>{0}</td>", "客户:"));
sb.Append(string.Format("<td>{0}</td>",dr["Cust_Name"]));
sb.Append(string.Format("<td>{0}</td>", "文本合同号:"));
sb.Append(string.Format("<td>{0}</td>", dr["Contract_No"]));
sb.Append(string.Format("<td>{0}</td>", "型号:"));
sb.Append(string.Format("<td>{0}</td>", dr["Model_Name"]+" --- "+dr["Serial_No"]));
sb.Append(string.Format("<td>{0}</td>", "总车价:"));
sb.Append(string.Format("<td>{0}</td>", dr["Sale_Amount"]));
sb.Append(string.Format("<td>{0}</td>", "不含履约保证金"));
sb.Append("</tr>");
}
if (cntTable > 1)
{
DataTable dtFirst = data.Tables[1];
int rowSpan = dtFirst.Rows.Count + 3;
sb.Append(string.Format("<tr><td rowspan='{0}'align='center'>{1}</td>", rowSpan, "首付款"));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 4, "应收款"));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 4, "实收款"));
sb.Append(string.Format("<td align='center'>{0}</td>", "差额"));
sb.Append("</tr>");
sb.Append(string.Format("<tr><td colspan='{0}'align='center'>{1}</td>", 2, "项目"));
sb.Append(string.Format("<td colspan='{0}'align='center'>{1}</td>", 2, "金额"));
sb.Append(string.Format("<td colspan='{0}'align='center'>{1}</td>", 2, "项目"));
sb.Append(string.Format("<td colspan='{0}'align='center'>{1}</td>", 2, "金额"));
sb.Append(string.Format("<td align='center'>{0}</td>", "应收-实收"));
sb.Append("</tr>");
foreach (DataRow dr in dtFirst.Rows)
{
sb.Append(string.Format("<tr><td colspan='{0}' align='center'>{1}</td>", 2, dr["Col_Type_Name"]));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, dr["Plan_Amount"]));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 2, dr["Col_Type_Name"]));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, dr["Col_Amount"]));
sb.Append(string.Format("<td align='right'>{0:N}</td>", dr["Remain_Amount"]));
sb.Append("</tr>");
PlanAmount += Convert.ToDecimal(dr["Plan_Amount"]);
RealAmount += Convert.ToDecimal(dr["Col_Amount"]);
}
sb.Append(string.Format("<tr><td colspan='{0}' align='center'>{1}</td>", 2, "首付小计"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, PlanAmount));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 2, "首付小计"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, RealAmount));
sb.Append(string.Format("<td align='right'>{0:N}</td>", PlanAmount - RealAmount));
sb.Append("</tr>");
if (cntTable > 2)
{
DataTable dtDetail = data.Tables[2];
int rowSpan2 = dtDetail.Rows.Count + 4;
sb.Append(string.Format("<tr><td rowspan='{0}' align='center'>{1}</td>", rowSpan2, "分期款"));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 4, "租赁款计划"));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 4, "租赁款实收"));
sb.Append(string.Format("<td align='center'>{0}</td>", " "));
sb.Append("</tr>");
sb.Append(string.Format("<tr><td colspan='{0}' align='center'>{1}</td>", 2, "日期"));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 2, "金额"));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 2, "日期"));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 2, "金额"));
sb.Append(string.Format("<td align='center'> {0}</td>", " "));
sb.Append("</tr>");
foreach (DataRow dr in dtDetail.Rows)
{
sb.Append(string.Format("<tr><td colspan='{0}' align='center'>{1}</td>", 2, dr["Plan_Date"] == DBNull.Value ? " " : Convert.ToDateTime(dr["Plan_Date"]).ToString("yyyy-MM-dd")));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, dr["Plan_Amount"] == DBNull.Value ? " " : dr["Plan_Amount"]));
sb.Append(string.Format("<td colspan='{0}' align='center'>{1}</td>", 2, dr["Real_Date"] == DBNull.Value ? " " : Convert.ToDateTime(dr["Real_Date"]).ToString("yyyy-MM-dd")));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, dr["Real_Amount"] == DBNull.Value ? " " : dr["Real_Amount"]));
sb.Append(string.Format("<td align='right'>{0:N}</td>", dr["Remain_Amount"]));
sb.Append("</tr>");
PlanAmountDetail += Convert.ToDecimal(dr["Plan_Amount"] == DBNull.Value ? 0 : dr["Plan_Amount"]);
RealAmountDetail += Convert.ToDecimal(dr["Real_Amount"] == DBNull.Value ? 0 : dr["Real_Amount"]);
if (dr["Plan_Date"] != DBNull.Value && Convert.ToDateTime(dr["Plan_Date"]) <= balanceDate)
{
BalanceAmount += Convert.ToDecimal(dr["Plan_Amount"] == DBNull.Value ? 0 : dr["Plan_Amount"]);
}
}
sb.Append(string.Format("<tr><td colspan='{0}'>{1}</td>", 2, "分期小计"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, PlanAmountDetail));
sb.Append(string.Format("<td colspan='{0}'>{1}</td>", 2, "分期小计"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, RealAmountDetail));
sb.Append(string.Format("<td align='right'>{0:N}</td>", PlanAmountDetail - RealAmountDetail));
sb.Append("</tr>");
sb.Append(string.Format("<tr><td colspan='{0}'>{1}</td>", 2, "分期应还"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, BalanceAmount));
sb.Append(string.Format("<td colspan='{0}'>{1}</td>", 2, "分期实还"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, RealAmountDetail));
sb.Append(string.Format("<td align='right'>{0:N}</td>", BalanceAmount - RealAmountDetail));
sb.Append("</tr>");
}
sb.Append(string.Format("<tr><td>{0}</td>", "到期"));
sb.Append(string.Format("<td colspan='{0}'>{1}</td>", 2, "到期应还"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, BalanceAmount + PlanAmount));
sb.Append(string.Format("<td colspan='{0}'>{1}</td>", 2, "到期实还"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, RealAmountDetail + RealAmount));
//sb.Append(string.Format("<td align='right'>{0:N}</td>", PlanAmountDetail - RealAmountDetail));
sb.Append(string.Format("<td align='right'>{0:N}</td>", (BalanceAmount + PlanAmount) - (RealAmountDetail + RealAmount)));
sb.Append("</tr>");
sb.Append(string.Format("<tr><td>{0}</td>", "总计"));
sb.Append(string.Format("<td colspan='{0}'>{1}</td>", 2, "总还款"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, PlanAmountDetail + PlanAmount));
sb.Append(string.Format("<td colspan='{0}'>{1}</td>", 2, "总还款"));
sb.Append(string.Format("<td colspan='{0}' align='right'>{1:N}</td>", 2, RealAmountDetail + RealAmount));
//sb.Append(string.Format("<td align='right'>{0:N}</td>", BalanceAmount - RealAmountDetail));
sb.Append(string.Format("<td align='right'>{0:N}</td>", (PlanAmountDetail + PlanAmount) - (RealAmountDetail + RealAmount)));
sb.Append("</tr>");
}
}
sb.Append("</table>");
sb.Append("</body>");
sb.Append("</html>");
webBrowserColDetail.DocumentText = sb.ToString();
}
-------------------------------------
打印预览按钮事件:
private void bbtPreview_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
IOleCommandTarget pCmdTarg =webBrowserColDetail.ActiveXInstance as IOleCommandTarget;
Guid CGID_MSHTML = GlobalConst.CGID_MSHTML;
string vTemplatePath = string.Empty;
pCmdTarg.Exec(ref CGID_MSHTML,
GlobalConst.IDM_PRINTPREVIEW,
(uint)OLECMDEXECOPT.OLECMDEXECOPT_PROMPTUSER,
null,
null);
}
-----------------------
需要引入的底层接口
------------------------
[ComImport(), Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
[PreserveSig()]
int QueryStatus([In, MarshalAs(UnmanagedType.Struct)] ref Guid
pguidCmdGroup, [MarshalAs(UnmanagedType.U4)] int cCmds,
[In, Out] IntPtr prgCmds, [In, Out] IntPtr pCmdText);
[PreserveSig()]
int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdExecOpt,
[In, MarshalAs(UnmanagedType.LPArray)] object[] pvaIn,
[In, Out, MarshalAs(UnmanagedType.LPArray)] object[] pvaOut);
}
public enum OLECMDEXECOPT
{
OLECMDEXECOPT_DODEFAULT,
OLECMDEXECOPT_PROMPTUSER,
OLECMDEXECOPT_DONTPROMPTUSER,
OLECMDEXECOPT_SHOWHELP
}
public static class GlobalConst
{
public const int MSOCMDEXECOPT_DONTPROMPTUSER = 2;
public const int IDM_PRINT = 0x1b;
public const int IDM_PRINTPREVIEW = 0x7d3;
public static readonly Guid CGID_MSHTML = new Guid("DE4BA900-59CA-11CF-9592-444553540000");
public static readonly Guid IID_OleCommandTarget = new Guid("B722BCCB-4E68-101B-A2BC-00AA00404770");
}
-----------------------------------------------------
添加引用
---------
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
----------------------------------
--总结:这种打印和一般的水晶报表打印其实一样,不过为何使用这种打印,咨询创始人说客户的要求形式使用报表不好实现.
--其实就是从后台返回一个DataSet,若有一个表非常容易,若是多个表就如上写代码了.
--可以试着把上述代码进行集成封装,所有的相关数据从XML或Appconfig读取,本人比较懒惰,这里只是提供打印思路.