RaUI/Source/RyPrint/SmartPrint.cs
2020-11-28 15:03:57 +08:00

377 lines
16 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}