377 lines
16 KiB
C#
377 lines
16 KiB
C#
|
using ryPrint;
|
|||
|
using ryPrint.Mod;
|
|||
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.ComponentModel;
|
|||
|
using System.Data;
|
|||
|
using System.Drawing;
|
|||
|
using System.Drawing.Printing;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Windows.Forms;
|
|||
|
|
|||
|
namespace RyPrint
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 如果涉及到分页打印,切勿在PrintPage事件中多次实例化
|
|||
|
/// </summary>
|
|||
|
public class SmartPrint
|
|||
|
{
|
|||
|
private Hashtable dt_list = new Hashtable();
|
|||
|
/// <summary>
|
|||
|
/// 设置获取加载的模板
|
|||
|
/// </summary>
|
|||
|
public string Mod_Xml { get; set; } = "";
|
|||
|
private PrintDocument _Print_Doc = null;
|
|||
|
public SmartPrint(string mod_xml,PrintDocument Print_Doc)
|
|||
|
{
|
|||
|
Mod_Xml = mod_xml;
|
|||
|
Print_Doc.BeginPrint += Print_Doc_BeginPrint;
|
|||
|
Print_Doc.PrintPage += Print_Doc_PrintPage;
|
|||
|
_Print_Doc = Print_Doc;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public SmartPrint(PrintDocument Print_Doc)
|
|||
|
{
|
|||
|
Print_Doc.BeginPrint += Print_Doc_BeginPrint;
|
|||
|
Print_Doc.PrintPage += Print_Doc_PrintPage;
|
|||
|
_Print_Doc = Print_Doc;
|
|||
|
}
|
|||
|
public SmartPrint()
|
|||
|
{
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 显示打印预览窗口
|
|||
|
/// </summary>
|
|||
|
public void ShowPreviewForm()
|
|||
|
{
|
|||
|
if (!_Print_Doc.PrinterSettings.IsValid)
|
|||
|
{ MessageBox.Show("当前打印机无效。请确认是否已安装打印机。","提示",MessageBoxButtons.OK,MessageBoxIcon.Information); return; }
|
|||
|
IsPreview = true;
|
|||
|
frmPrintPreview frm = new frmPrintPreview();
|
|||
|
frm._SmartPrint = this;
|
|||
|
frm.PrintDoc = _Print_Doc;
|
|||
|
frm.ShowDialog();
|
|||
|
}
|
|||
|
private void Print_Doc_PrintPage(object sender, PrintPageEventArgs e)
|
|||
|
{
|
|||
|
Print(Mod_Xml, e, IsPreview);
|
|||
|
}
|
|||
|
|
|||
|
private void Print_Doc_BeginPrint(object sender, PrintEventArgs e)
|
|||
|
{
|
|||
|
StartPrint();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 左边距
|
|||
|
/// </summary>
|
|||
|
public int MarginLeft { get; set; } = 0;
|
|||
|
/// <summary>
|
|||
|
/// 顶部边距
|
|||
|
/// </summary>
|
|||
|
public int MarginTop { get; set; } = 0;
|
|||
|
/// <summary>
|
|||
|
/// 单位是否是英寸,如果false,则是毫米,默认false。
|
|||
|
/// </summary>
|
|||
|
public bool IsInch { get; set; } = false;
|
|||
|
/// <summary>
|
|||
|
/// 是否是预览
|
|||
|
/// </summary>
|
|||
|
public bool IsPreview { get; set; } = false;
|
|||
|
public string FontName { get; set; } = "黑体";
|
|||
|
private int _curPageIndex = 0;
|
|||
|
/// <summary>
|
|||
|
/// 获取或设置当前打印的是第几页,从0开始计数
|
|||
|
/// </summary>
|
|||
|
public int curPageIndex
|
|||
|
{
|
|||
|
get { return _curPageIndex; }
|
|||
|
set
|
|||
|
{
|
|||
|
if (value < 0) { _curPageIndex=0; }
|
|||
|
else { _curPageIndex= value; }
|
|||
|
}
|
|||
|
}
|
|||
|
private int _MaxPage = -1;
|
|||
|
/// <summary>
|
|||
|
/// 获取或设置当前最多打印到第几页,从0开始计数,-1表示打印到结束
|
|||
|
/// </summary>
|
|||
|
public int MaxPage
|
|||
|
{
|
|||
|
get { return _MaxPage; }
|
|||
|
set
|
|||
|
{
|
|||
|
if (value < 0) { _MaxPage = -1; }
|
|||
|
else { _MaxPage = value; }
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 设置纸张名称
|
|||
|
/// </summary>
|
|||
|
public string PaperName { get; set; } = "打印内容";
|
|||
|
/// <summary>
|
|||
|
/// 是否横向打印
|
|||
|
/// </summary>
|
|||
|
public bool Landscape { get; set; } = true;
|
|||
|
/// <summary>
|
|||
|
/// 是否打印多页,如果设为true,有多页文本,则打印多页,没有则打印一页。
|
|||
|
/// </summary>
|
|||
|
public bool PrintMorePages { get; set; } = true;
|
|||
|
public delegate void DataSetHandler(string DataSource,out DataTable ds);
|
|||
|
[Description("获取数据表时激发")]
|
|||
|
public event DataSetHandler OnDataSet;
|
|||
|
public void StartPrint()
|
|||
|
{
|
|||
|
//curPageIndex = 0;
|
|||
|
dt_list.Clear();
|
|||
|
ryCommon.Storage tStor_set = new ryCommon.Storage(Mod_Xml);
|
|||
|
tStor_set.SelectNode2("id", "set");
|
|||
|
double mmWidth = tStor_set.GetAttrValue("Width", 0d);
|
|||
|
double mmHeight = tStor_set.GetAttrValue("Height", 0d);
|
|||
|
PaperSize sPSize = new PaperSize(PaperName, (int)RySet.MMToInches(mmHeight * 100), (int)RySet.MMToInches(mmWidth * 100));//267为英寸转厘米为8厘米 //PaperSize sPSize = new PaperSize("快递单", (int)pixelsToInches(image.Width * 100), (int)pixelsToInches(image.Height * 100));
|
|||
|
if (!Landscape)
|
|||
|
{
|
|||
|
sPSize = new PaperSize(PaperName, (int)RySet.MMToInches(mmWidth * 100), (int)RySet.MMToInches(mmHeight * 100));//267为英寸转厘米为8厘米
|
|||
|
}
|
|||
|
_Print_Doc.DefaultPageSettings.PaperSize = sPSize;
|
|||
|
}
|
|||
|
public void Print()
|
|||
|
{
|
|||
|
curPageIndex = 0;
|
|||
|
MaxPage = -1;
|
|||
|
IsPreview = false;
|
|||
|
_Print_Doc.PrinterSettings.FromPage = 0;
|
|||
|
_Print_Doc.Print();
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 打印
|
|||
|
/// </summary>
|
|||
|
/// <param name="mod_xml">打印模板</param>
|
|||
|
/// <param name="e">打印参数</param>
|
|||
|
/// <param name="isPreview">是否是预览</param>
|
|||
|
public void Print(string mod_xml, PrintPageEventArgs e,bool isPreview)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
e.Graphics.PageUnit = IsInch ? GraphicsUnit.Inch : GraphicsUnit.Millimeter;
|
|||
|
#region 根据模板打印
|
|||
|
ryCommon.Storage tStor_set = new ryCommon.Storage(mod_xml);
|
|||
|
tStor_set.SelectNode2("id", "set");
|
|||
|
double mmWidth = tStor_set.GetAttrValue("Width", 0d);
|
|||
|
double mmHeight = tStor_set.GetAttrValue("Height", 0d);
|
|||
|
if (IsInch)
|
|||
|
{
|
|||
|
mmWidth = RySet.MMToInches(mmWidth);
|
|||
|
mmHeight = RySet.MMToInches(mmHeight);
|
|||
|
}
|
|||
|
string picPath = RySet.GetTruePath(tStor_set.GetAttrValue("PreviewPicPath", ""));
|
|||
|
tStor_set.SelectNode2("id", "print_xml");
|
|||
|
ryCommon.Storage tStor = new ryCommon.Storage(tStor_set.GetAttrValue("Value"));
|
|||
|
System.Xml.XmlNodeList list = tStor.GetList();
|
|||
|
if (System.IO.File.Exists(picPath))
|
|||
|
{
|
|||
|
Image image = Image.FromFile(picPath);
|
|||
|
if (isPreview)
|
|||
|
{
|
|||
|
|
|||
|
Bitmap pic = (Bitmap)image;
|
|||
|
//pic.SetResolution(dpiValue, dpiValue);
|
|||
|
e.Graphics.DrawImage(pic, 0, 0, (float)mmWidth, (float)mmHeight);
|
|||
|
}
|
|||
|
}
|
|||
|
for (int i = 0; i < list.Count; i++)
|
|||
|
{
|
|||
|
tStor.SelectNode3(list[i]);
|
|||
|
Font _Font = new Font(FontName, tStor.GetAttrValueByInt("FontSize", 10), FontStyle.Regular);
|
|||
|
bool Multiline = tStor.GetAttrValueByBool("Multiline", false);
|
|||
|
SizeF size = new SizeF((float)(tStor.GetAttrValue("Width", 100f)), (float)(tStor.GetAttrValue("Height", 21f)));
|
|||
|
PointF location = new PointF((float)(tStor.GetAttrValue("Left", 0f) + MarginLeft), (float)(tStor.GetAttrValue("Top", 0f) + MarginTop));
|
|||
|
if (IsInch)
|
|||
|
{
|
|||
|
size = new SizeF(RySet.MMToInches(size.Width), RySet.MMToInches(size.Height));
|
|||
|
location = new PointF(RySet.MMToInches(location.X), RySet.MMToInches(location.Y));
|
|||
|
}
|
|||
|
string title = tStor.GetAttrValue("Title");
|
|||
|
ClsProperty.En_Type _type = ClsProperty.En_Type.自定义;
|
|||
|
try
|
|||
|
{
|
|||
|
_type = (ClsProperty.En_Type)tStor.GetAttrValueByInt("sType", 0);
|
|||
|
}
|
|||
|
catch { }
|
|||
|
List<string> value_list = new List<string>();
|
|||
|
#region 转换值
|
|||
|
switch (_type)
|
|||
|
{
|
|||
|
case ClsProperty.En_Type.自定义:
|
|||
|
string format = tStor.GetAttrValue("format");
|
|||
|
if (format == "")
|
|||
|
{
|
|||
|
if (tStor.GetAttrValue("value") == "")
|
|||
|
{ value_list.Add(title); }
|
|||
|
else
|
|||
|
{
|
|||
|
value_list.Add(tStor.GetAttrValue("value"));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
value_list.Add(DateTime.Now.ToString(format));
|
|||
|
}
|
|||
|
break;
|
|||
|
case ClsProperty.En_Type.数据字段:
|
|||
|
string datasource = tStor.GetAttrValue("DataSource");
|
|||
|
if (datasource != "")
|
|||
|
{
|
|||
|
DataTable dt = new DataTable();
|
|||
|
HashItem item = new HashItem();
|
|||
|
if (!dt_list.ContainsKey(datasource))
|
|||
|
{
|
|||
|
OnDataSet?.Invoke(datasource, out dt);
|
|||
|
item.dt = dt;
|
|||
|
dt_list.Add(datasource, item);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
item = (HashItem)dt_list[datasource];
|
|||
|
if (item.dt!= null)
|
|||
|
dt = item.dt;
|
|||
|
}
|
|||
|
if (!dt.Columns.Contains(tStor.GetAttrValue("value"))) { item.ReadEnd = true; continue; }
|
|||
|
int PageCount = tStor.GetAttrValue("PageCount", 0);
|
|||
|
int startRow = curPageIndex* PageCount;
|
|||
|
int endRow = dt.Rows.Count;
|
|||
|
if(PageCount>0)
|
|||
|
{
|
|||
|
if((curPageIndex+1) * PageCount>= dt.Rows.Count)
|
|||
|
{
|
|||
|
endRow = dt.Rows.Count;
|
|||
|
item.ReadEnd = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
endRow = (curPageIndex + 1) *PageCount;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
item.ReadEnd = true;
|
|||
|
}
|
|||
|
dt_list[datasource] = item;
|
|||
|
for (int m = startRow; m < endRow; m++)
|
|||
|
{
|
|||
|
value_list.Add(dt.Rows[m][tStor.GetAttrValue("value")].ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
float total_top = location.Y;
|
|||
|
#region 打印内容
|
|||
|
for (int k = 0; k < value_list.Count; k++)
|
|||
|
{
|
|||
|
location.Y = total_top;
|
|||
|
string value = value_list[k];
|
|||
|
float rowHeight = e.Graphics.MeasureString(value + "有", _Font).Height;
|
|||
|
if (value != "")
|
|||
|
{
|
|||
|
StringFormat sf = new StringFormat();
|
|||
|
Brush fontBrush = Brushes.Black;
|
|||
|
if (tStor.GetAttrValue("NoPrint", false))
|
|||
|
{
|
|||
|
if (isPreview)
|
|||
|
{
|
|||
|
fontBrush = Brushes.Blue;
|
|||
|
}
|
|||
|
else
|
|||
|
{ continue; }
|
|||
|
}
|
|||
|
if (Multiline)
|
|||
|
{
|
|||
|
//sf.Alignment = StringAlignment.Center;
|
|||
|
//sf.LineAlignment = StringAlignment.Center;
|
|||
|
RectangleF rect = new RectangleF(location, size);
|
|||
|
rowHeight = rect.Height;
|
|||
|
e.Graphics.DrawString(value, _Font, fontBrush, rect, sf);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
#region 单行打印
|
|||
|
switch (tStor.GetAttrValue("align"))
|
|||
|
{
|
|||
|
case "Left":
|
|||
|
sf.Alignment = StringAlignment.Near;
|
|||
|
break;
|
|||
|
case "Right":
|
|||
|
sf.Alignment = StringAlignment.Far;
|
|||
|
break;
|
|||
|
case "Center":
|
|||
|
sf.Alignment = StringAlignment.Center;
|
|||
|
break;
|
|||
|
}
|
|||
|
//sf.LineAlignment = sf.Alignment;
|
|||
|
if (sf.Alignment == StringAlignment.Center)
|
|||
|
{
|
|||
|
SizeF _size = e.Graphics.MeasureString(value, _Font);
|
|||
|
if (size.Width < _size.Width) { size.Width = _size.Width; }
|
|||
|
size.Height = _size.Height;
|
|||
|
RectangleF rect = new RectangleF(location, size);
|
|||
|
sf.LineAlignment = sf.Alignment;
|
|||
|
e.Graphics.DrawString(value, _Font, fontBrush, rect, sf);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
e.Graphics.DrawString(value, _Font, fontBrush, location, sf);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|
|||
|
if (IsInch)
|
|||
|
{ total_top += rowHeight + RySet.MMToInches(tStor.GetAttrValue("LineSpace", 0)); }
|
|||
|
else
|
|||
|
{
|
|||
|
total_top += rowHeight + tStor.GetAttrValue("LineSpace", 0);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
catch { }
|
|||
|
#region 判断记录是否已经打印完
|
|||
|
bool PageEnd = true;
|
|||
|
foreach (DictionaryEntry de in dt_list)
|
|||
|
{
|
|||
|
HashItem _item = (HashItem)de.Value;
|
|||
|
if (!_item.ReadEnd)
|
|||
|
{
|
|||
|
PageEnd = false;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (PageEnd) { e.HasMorePages = false; }///如果已经是尾页,则不继续打印
|
|||
|
else
|
|||
|
{
|
|||
|
if(MaxPage>0)
|
|||
|
{
|
|||
|
if(curPageIndex>= MaxPage)
|
|||
|
{
|
|||
|
e.HasMorePages = false;
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
e.HasMorePages = true;
|
|||
|
curPageIndex++;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|
|||
|
class HashItem
|
|||
|
{
|
|||
|
public DataTable dt=new DataTable();
|
|||
|
public bool ReadEnd = false;
|
|||
|
}
|
|||
|
}
|