在C#的打印中,有些时候需要将打印的纸张进行角度转换,可以通过如下步骤去实现:
1. 首先我们需要定义纸张转换函数(后续打印设置类里面有)
#region 单位转换
/// <summary>
/// 毫米转为像素(注:dpi分水平和垂直,获取方法为得到 Graphics 的实例化对象 g,调用g.DpiX、g.DpiY)
/// </summary>
/// <param name="mm">毫米</param>
/// <param name="fDPI">分辨率(水平/垂直)</param>
/// <returns></returns>
public static float MillimetersToPixel(float mm, float fDPI)
{
//毫米转像素:mm * dpi / 25.4
return (float)Math.Round((mm * fDPI / 25.4f), 2);
}
/// <summary>
/// 像素转为毫米(注:dpi分水平和垂直,获取方法为得到 Graphics 的实例化对象 g,调用g.DpiX、g.DpiY)
/// </summary>
/// <param name="px">像素</param>
/// <param name="fDPI">分辨率(水平/垂直)</param>
/// <returns></returns>
public static float PixelToMillimeters(float px, float fDPI)
{
//像素转毫米:px * 25.4 / dpi
return (float)Math.Round(((px * 25.4f) / fDPI), 2); ;
}
/// <summary>
/// 英寸到像素
/// </summary>
/// <param name="inches"></param>
/// <returns></returns>
public static float InchesToPixels(float inches, float fDPI)
{
return (float)Math.Round(inches * fDPI, 2);
}
/// <summary>
/// 像素到英寸
/// </summary>
/// <param name="px"></param>
/// <returns></returns>
public static float PixelsToInches(float px, float fDPI)
{
return (float)Math.Round(px / fDPI, 2);
}
/// <summary>
/// 毫米到英寸
/// </summary>
/// <param name="mm"></param>
/// <returns></returns>
public static float MillimetersToInches(float mm)
{
return (float)Math.Round(mm / 25.4f, 2);
}
/// <summary>
/// 英寸到毫米
/// </summary>
/// <param name="mm"></param>
/// <returns></returns>
public static float InchesToMillimeters(float Inches)
{
return (float)Math.Round(Inches * 25.4f, 2);
}
#endregion
2. 定义纸张的大小,打印设置等信息
private static void SetPageSetting(PrintSetData vSet, PrintDocument vDocument)
{
//设置打印机
PrinterSettings vSetting = vDocument.PrinterSettings;
vSetting.PrinterName = PrintSet.PrintName;
//设置纸张信息
PageSettings vPageSetting = new PageSettings();
PaperSize vPaperSize = null;
int vWidth = (int)(PrintSetData.MillimetersToInches(vSet.PageWidth) * 100); // PageWidth - 毫米
int vHeight = (int)(PrintSetData.MillimetersToInches(vSet.PageHeight) * 100); // PageHeight - 毫米
//是否需要将纸张的宽度和高度互换
if (Math.Abs(180 - vSet.PrintAngle) == 90)
{
int vTemp = vWidth;
vWidth = vHeight;
vHeight = vTemp;
}
//纸张的名字,当纸张不存在时,则转换
string vPaperName = string.Format("Order{0}*{1}", vWidth, vHeight);
foreach (PaperSize ps in vDocument.PrinterSettings.PaperSizes)
{
if (ps.PaperName == vPaperName)
{
vPaperSize = ps;
}
}
if (vPaperSize == null)
{
vPaperSize = new PaperSize(vPaperName, vWidth, vHeight);
}
vPageSetting.PaperSize = vPaperSize;
vDocument.DefaultPageSettings = vPageSetting;
}
3. 定义打印旋转函数
/// <summary>
/// 旋转函数
/// </summary>
/// <param name="vSet">旋转的设置</param>
/// <param name="vDocument">旋转的文档</param>
/// <param name="e">旋转的参数</param>
private static void Angle(PrintSetData vSet, PrintDocument vDocument, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
if (vSet.PrintAngle > 0) //判断旋转角度 0、90、180、270
{
int vWidth = vDocument.DefaultPageSettings.PaperSize.Width;
int vHeight = vDocument.DefaultPageSettings.PaperSize.Height;
if (vSet.PrintAngle == 90)
{
g.TranslateTransform(vWidth, 0);
}
else if (vSet.PrintAngle == 180)
{
g.TranslateTransform(vWidth, vHeight);
}
else if (vSet.PrintAngle == 270)
{
g.TranslateTransform(0, vHeight);
}
g.RotateTransform(vSet.PrintAngle);
}
}
4. 调用打印
public static PrintDocument GetPrintDocument(PrintSetData vSet, PrintData vPD)
{
PrintDocument vDocument = new PrintDocument();
vDocument.DocumentName = "我的打印机";
SetPageSetting(vSet, vDocument);
vDocument.PrintPage += delegate(object sender, PrintPageEventArgs e)
{
Angle(vSet, vDocument, e);
WriteContent(vSet, vDocument, e, vPD);
};
return vDocument;
}
5. 写入打印内容
private static void WriteContent(PrintSetData vSet, PrintDocument vDocument, PrintPageEventArgs e, PrintData vPD)
{
Graphics g = e.Graphics;
Font vFont = new Font("黑体", vSet.FontSize);
Brush vBrush = new SolidBrush(Color.Black);
#region 写入文字
foreach (string vKey in PrintSetData.TextList)
{
string vTopKey = vKey + "Top";
string vLeftKey = vKey + "Left";
string vIsKey = "Is" + vKey;
bool vIs = vSet.PositionDate.GetBoolean(vIsKey);
int vTop = vSet.PositionDate.GetInt(vTopKey);
int vLeft = vSet.PositionDate.GetInt(vLeftKey);
string vString = string.Empty;
switch (vKey)
{
case "CreateDate":
vString = "下单时间 : " + vPD.CreateDate;
break;
case "Order":
vString = "订单号 : " + vPD.Order;
break;
case "ProductName":
vString = "产品名称 : " + vPD.ProductName;
break;
case "Code":
vString = "辅助码 : " + vPD.Code;
break;
case "Window":
vString = "窗口 : " + vPD.Window;
break;
case "Person":
vString = "人数 : " + vPD.Person;
break;
case "Price":
vString = "价格 : " + vPD.Price;
break;
}
if (vIs)
{
g.DrawString(vString, vFont, vBrush, new Point(vLeft, vTop));
}
}
#endregion
#region 写入辅助码,有一定的偏差,注意调整
{
int vTop = vSet.PositionDate.GetInt("ImageTop");
int vLeft = vSet.PositionDate.GetInt("ImageLeft");
int vMoveWidth = vSet.ImageWidth / 7;
int vMoveHeight = vSet.ImageHeight / 7;
Bitmap bmp = QrHelper.Write(vPD.Code, vSet.ImageWidth + vMoveWidth, vSet.ImageHeight + vMoveHeight);
g.DrawImage(bmp, new Point(vLeft, vTop));
bmp.Dispose();
}
#endregion
}
6. 打印设置实体
public class PrintSetData
{
#region 静态属性
static PrintSetData()
{
TextList = new List<string>() {
"CreateDate",
"Order",
"ProductName",
"Code",
"Window",
"Person",
"Price"
};
}
public static readonly int DefaultX = 15;
public static readonly int DefaultY = 15;
public static List<string> TextList { get; private set; }
#endregion
public PrintSetData()
{
this.IsAuto = true;
this.PositionDate = new PositionInfo();
this.WriteAllCheck();
this.WriteDefault();
}
/// <summary>
/// 自动计算
/// </summary>
public bool IsAuto { get; set; }
#region 页面属性
/// <summary>
/// 纸张宽度
/// </summary>
public int PageWidth { get; set; }
/// <summary>
/// 纸张高度
/// </summary>
public int PageHeight { get; set; }
#endregion
#region 文字属性
/// <summary>
/// 文字大小
/// </summary>
public int FontSize { get; set; }
#endregion
#region 图片属性
/// <summary>
/// 图片宽度
/// </summary>
public int ImageWidth { get; set; }
/// <summary>
/// 图片高度
/// </summary>
public int ImageHeight { get; set; }
#endregion
#region 打印设置
/// <summary>
/// 打印角度
/// </summary>
public int PrintAngle { get; set; }
/// <summary>
/// 打印机
/// </summary>
public string PrintName { get; set; }
#endregion
/// <summary>
/// 所有的位置数据
/// </summary>
public PositionInfo PositionDate { get; set; }
#region 属性操作函数
/// <summary>
/// 选择所有的CheckBox
/// </summary>
private void WriteAllCheck()
{
foreach (string vName in TextList)
{
this.PositionDate.SetValue("Is" + vName, true);
}
this.WriteDefault();
}
/// <summary>
/// 写入默认属性
/// </summary>
public void WriteDefault()
{
this.PageWidth = this.PageWidth > 0 ? this.PageWidth : 100;
this.PageHeight = this.PageHeight > 0 ? this.PageHeight : 120;
this.FontSize = this.FontSize > 0 ? this.FontSize : 12;
#region 图片
this.ImageWidth = this.ImageWidth > 0 ? this.ImageWidth : 77;
this.ImageHeight = this.ImageHeight > 0 ? this.ImageHeight : 77;
#endregion
if (this.IsAuto)
{
this.ClearPosition();
}
this.ResizePosition();
}
/// <summary>
/// 清除位置
/// </summary>
private void ClearPosition()
{
foreach (string vName in TextList)
{
this.PositionDate.SetValue(vName + "Top", 0);
this.PositionDate.SetValue(vName + "Left", 0);
}
this.PositionDate.SetValue("ImageTop", 0);
this.PositionDate.SetValue("ImageLeft", 0);
}
/// <summary>
/// 计算位置
/// </summary>
private void ResizePosition()
{
int index = 0;
foreach (string vName in TextList)
{
if (this.PositionDate.GetBoolean("Is" + vName))
{
this.SetPostionDate(vName, DefaultX, ref index);
}
}
this.SetPostionDate("Image", DefaultX, ref index);
//this.SetPostionDate("Image", this.GetDefaultImageLeft(), ref index);
}
#endregion
#region 当位置为0时,根据序号生成位置
private void SetPostionDate(string vName, int vDefault, ref int index)
{
int vLeft = this.PositionDate.GetInt(vName + "Left");
int vTop = this.PositionDate.GetInt(vName + "Top");
this.PositionDate[vName + "Left"] = vLeft > 0 ? vLeft : vDefault;
this.PositionDate[vName + "Top"] = vTop > 0 ? vTop : this.GetFontTop(index++);
}
#endregion
#region 计算位置 函数
private int GetFontTop(int index)
{
return DefaultY + (this.FontSize * 2 + 8) * index;
}
#endregion
#region 位置内部类
public class PositionInfo : Dictionary<string, object>
{
public PositionInfo()
{
}
#region 属性
public int ImageLeft
{
get { return this.GetInt("ImageLeft"); }
set { this.SetValue("ImageLeft", value); }
}
public int ImageTop
{
get { return this.GetInt("ImageTop"); }
set { this.SetValue("ImageTop", value); }
}
#endregion
#region 设置获取值
public bool GetBoolean(string vName)
{
return StringHelper.GetBoolean(StringHelper.GetString(this.GetValue(vName)));
}
public int GetInt(string vName)
{
return StringHelper.GetInt(this.GetValue(vName));
}
public object GetValue(string vName)
{
if (this.ContainsKey(vName))
{
return this[vName];
}
return null;
}
public void SetValue(string vName, object vValue)
{
this[vName] = vValue;
}
#endregion
}
#endregion
#region 单位转换
/// <summary>
/// 毫米转为像素(注:dpi分水平和垂直,获取方法为得到 Graphics 的实例化对象 g,调用g.DpiX、g.DpiY)
/// </summary>
/// <param name="mm">毫米</param>
/// <param name="fDPI">分辨率(水平/垂直)</param>
/// <returns></returns>
public static float MillimetersToPixel(float mm, float fDPI)
{
//毫米转像素:mm * dpi / 25.4
return (float)Math.Round((mm * fDPI / 25.4f), 2);
}
/// <summary>
/// 像素转为毫米(注:dpi分水平和垂直,获取方法为得到 Graphics 的实例化对象 g,调用g.DpiX、g.DpiY)
/// </summary>
/// <param name="px">像素</param>
/// <param name="fDPI">分辨率(水平/垂直)</param>
/// <returns></returns>
public static float PixelToMillimeters(float px, float fDPI)
{
//像素转毫米:px * 25.4 / dpi
return (float)Math.Round(((px * 25.4f) / fDPI), 2); ;
}
/// <summary>
/// 英寸到像素
/// </summary>
/// <param name="inches"></param>
/// <returns></returns>
public static float InchesToPixels(float inches, float fDPI)
{
return (float)Math.Round(inches * fDPI, 2);
}
/// <summary>
/// 像素到英寸
/// </summary>
/// <param name="px"></param>
/// <returns></returns>
public static float PixelsToInches(float px, float fDPI)
{
return (float)Math.Round(px / fDPI, 2);
}
/// <summary>
/// 毫米到英寸
/// </summary>
/// <param name="mm"></param>
/// <returns></returns>
public static float MillimetersToInches(float mm)
{
return (float)Math.Round(mm / 25.4f, 2);
}
/// <summary>
/// 英寸到毫米
/// </summary>
/// <param name="mm"></param>
/// <returns></returns>
public static float InchesToMillimeters(float Inches)
{
return (float)Math.Round(Inches * 25.4f, 2);
}
#endregion
}
7. 定义的打印数据
public class PrintData
{
public string CreateDate { get; set; }
public string Order { get; set; }
public string ProductName { get; set; }
public string Code { get; set; }
public string Window { get; set; }
public string Person { get; set; }
public string Price { get; set; }
}