You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2166 lines
83 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using System.Linq;
using Newtonsoft.Json.Linq;
using System.IO;
using BarcodeLib;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using QRCoder;
namespace POSV.Printer
{
public enum RowFormat
{
None = 0,
Line = 1,
Column = 2,
Grid = 3,
Barcode = 4,
QRCode = 5,
Bitmap = 6
}
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class PrinterTemplate
{
[JsonProperty(PropertyName = "pager")]
public PagerType PagerType { get; set; }
/// <summary>
/// 单行最大打印半角字符数量
/// </summary>
[JsonProperty(PropertyName = "maxlength")]
public int MaxLength { get; set; }
private List<RowTemplate> _rows = new List<RowTemplate>();
[JsonProperty(PropertyName = "rows")]
public List<RowTemplate> Rows
{
get
{
return _rows;
}
}
public void AddRow(RowTemplate row)
{
this.Rows.Add(row);
}
public List<PrintContent> Parse(PrinterObject pobject , List<VariableValue> args, int headerLine = 0, int footerLine = 0)
{
if (pobject == null)
{
pobject = new PrinterObject();
}
if (args == null)
{
args = new List<VariableValue>();
}
var result = new List<PrintContent>();
EscPosCommand command = pobject.EscPosCommand;
bool isInit = false;
//钱箱指令
if (pobject.OpenCashbox)
{
result.Add(OpenCashbox(pobject));
isInit = true;
}
//退纸指令
if(pobject.FeedBackRow > 0)
{
var content = new PrintContent();
content.Format = RowFormat.Line;
var bs = new StringBuilder();
if (!isInit)
{
bs.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
var rows = pobject.FeedBackRow;
while (rows > 0)
{
//反向走纸
bs.Append(ParseEscPosCommand(command.FeedBackCommand.Replace('n', '1')));
rows--;
}
content.Content = bs;
result.Add(content);
}
if(headerLine > 0)
{
var _header = new PrintContent();
_header.Format = RowFormat.Line;
var bs = new StringBuilder();
if (!isInit)
{
bs.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
for (int i = 0; i < headerLine; i++)
{
bs.AppendLine("");
}
_header.Content = bs;
_header.AlignStyle = AlignStyle.;
_header.FontStyle = FontStyle.;
_header.BitmapFile = string.Empty;
result.Add(_header);
}
foreach (var rows in this.Rows)
{
switch (rows.RowFormat)
{
case RowFormat.Line:
{
//行数据模版
var template = JSON.Deserialize<LineTemplate>(rows.Template.ToString());
//数据源参数,无论单行还是列表数据源采用List方式兼容单行选择集合数据源重复行打印
var data = new List<Dictionary<string , string>>();
//包含数据源参数,重置
if (args.Exists(x => x.Key == template.DataSourceKey))
{
//当前数据源
var vars = args.FindLast(x => x.Key == template.DataSourceKey);
//List集合数据
if (vars.DataType == DataType.List)
{
data = JSON.Deserialize<List<Dictionary<string , string>>>(vars.Value.ToString());
}
else
{
var row = JSON.Deserialize<Dictionary<string , string>>(vars.Value.ToString());
data.Add(row);
}
}
var content = new PrintContent();
content.Format = RowFormat.Line;
var sb = new StringBuilder();
int inx = 0;
//替换变量
foreach (var row in data)
{
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
//字体指令
sb.Append(ParseFontStyle(template.FontStyle , command));
//打印内容
sb.Append(ReplaceArgs(template.Content , row , this.MaxLength , template.AlignStyle , template.FontStyle , template.LineStyle));
if(data.Count > 1 && inx + 1 != data.Count)
{
sb.AppendLine("");
}
inx++;
}
content.Content = sb;
result.Add(content);
}
break;
case RowFormat.Column:
{
var template = JSON.Deserialize<List<LineTemplate>>(rows.Template.ToString());
var lists = MergeLineTemplate(template[0] , template[1] , args , command);
var content = new PrintContent();
content.Format = RowFormat.Column;
var sb = new StringBuilder();
foreach (var str in lists)
{
sb.Append(str);
}
content.Content = sb;
result.Add(content);
}
break;
case RowFormat.Grid:
{
var template = JSON.Deserialize<GridTemplate>(rows.Template.ToString());
//数据源参数,必须为列表
var data = new List<Dictionary<string , string>>();
//包含数据源参数,重置
if (args.Exists(x => x.Key == template.DataSourceKey))
{
//当前数据源
var vars = args.FindLast(x => x.Key == template.DataSourceKey);
//List集合数据
if (vars.DataType == DataType.List)
{
data = JSON.Deserialize<List<Dictionary<string , string>>>(vars.Value.ToString());
}
else
{
var row = JSON.Deserialize<Dictionary<string , string>>(vars.Value.ToString());
data.Add(row);
}
}
//判断是否符合打印条件
var notAllowEmpty = template.NotAllowEmpty;
if (notAllowEmpty && data.Count == 0)
{
continue;
}
var content = new PrintContent();
content.Format = RowFormat.Grid;
var sb = new StringBuilder();
//标题行添加下划线
string paddingChar = this.ParseLineType(template.LineStyle);
var _columnWidth = new Dictionary<int , int>();
int _column = 0;
int _sum = 0;
//判断是否打印表头
var notAllowHeader = template.NotAllowHeader;
var fontStyle = FontStyle.;
if (!notAllowHeader)
{
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
//表头采用正常字体打印
var notAllowHeaderFontStyle = template.HeaderFontStyle;
if (!notAllowHeaderFontStyle)
{
fontStyle = template.FontStyle;
}
//字体指令
sb.Append(ParseFontStyle(fontStyle , command));
}
foreach (ColumnTempate col in template.Columns)
{
_sum += col.Length;
_columnWidth.Add(_column++ , _sum);
var title = ReplaceArgs(col.Name , null , col.Length , col.AlignStyle , fontStyle , LineStyle.);
int titleLength = GetPrintStringLength(title , fontStyle);
int titleDiff = col.Length - titleLength;
if (!notAllowHeader)
{
sb.Append(title + ("".PadRight(titleDiff < 0 ? 0 : titleDiff , Convert.ToChar(" "))));
}
}
//提交标题行打印
if (!notAllowHeader)
{
sb.AppendLine("");
}
//提交下划线打印
if (!string.IsNullOrEmpty(paddingChar.Trim()))
{
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
//字体指令
sb.Append(ParseFontStyle(FontStyle. , command));
sb.AppendLine("".PadRight(this.MaxLength , Convert.ToChar(paddingChar)));
}
//模版数据
for (int row = 0; row < data.Count; row++)
{
//判断是否允许输出合计行,并且是最后一行
if (template.ContainsTotalRow && row + 1 == data.Count)
{
//不允许打印,结束本次循环
if (!template.OutputTotalRow)
{
continue;
}
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
//字体指令
sb.Append(ParseFontStyle(FontStyle. , command));
//下划线,隔离合计行和明细
sb.AppendLine("".PadRight(this.MaxLength , Convert.ToChar(paddingChar)));
}
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
int cols = 0;
var _offset = new Dictionary<int , int>();
foreach (ColumnTempate col in template.Columns)
{
if (template.AllowNewLine)
{
var _content = ReplaceArgs(col.DataMember , template.AllowNewLine , data[row] , col.Length , col.AlignStyle , template.FontStyle , LineStyle.);
int len = GetPrintStringLength(_content, template.FontStyle);
//长度超出,允许独占一行
if (len > col.Length)
{
_offset[cols] = _columnWidth[cols];
}
else
{
_offset[cols] = 0;
}
//独占一行的内容
if (_offset[cols] > 0)
{
int width = cols == 0 ? 0 : _offset[cols - 1];
//字体指令
//独占一行的进行左对齐初始化,发现在打印图片后会导致这里居中显示
sb.Append(ParseEscPosCommand(command.AlignLeftCommand));
sb.Append(ParseFontStyle(template.FontStyle , command));
sb.AppendLine("".PadLeft(width , ' ') + _content);
}
else
{
int width = cols == 0 ? 0 : _offset[cols - 1];
//字体指令
sb.Append(ParseFontStyle(FontStyle. , command));
sb.Append("".PadLeft(width , ' '));
int diff = col.Length - len;
//字体指令
sb.Append(ParseFontStyle(template.FontStyle , command));
sb.Append(_content );
//字体指令
sb.Append(ParseFontStyle(FontStyle. , command));
sb.Append("".PadRight(diff < 0 ? 0 : diff , ' '));
}
}
else
{
var _content = ReplaceArgs(col.DataMember , template.AllowNewLine , data[row] , col.Length , col.AlignStyle , template.FontStyle , LineStyle.);
int len = GetPrintStringLength(_content,template.FontStyle);
int diff = col.Length - len;
//字体指令
sb.Append(ParseFontStyle(template.FontStyle , command));
sb.Append(_content + ("".PadRight(diff < 0 ? 0 : diff , ' ')));
}
cols++;
}
//包含合计行,而且不允许输出
if (template.ContainsTotalRow && !template.OutputTotalRow)
{
if (row + 2 != data.Count)
{
sb.AppendLine("");
}
}
else
{
if (row + 1 != data.Count)
{
sb.AppendLine("");
}
}
}
content.Content = sb;
result.Add(content);
}
break;
case RowFormat.Barcode:
{
//行数据模版
var template = JSON.Deserialize<BarcodeTemplate>(rows.Template.ToString());
//数据源参数,无论单行还是列表数据源采用List方式兼容单行选择集合数据源重复行打印
var data = new List<Dictionary<string , string>>();
//包含数据源参数,重置
if (args.Exists(x => x.Key == template.DataSourceKey))
{
//当前数据源
var vars = args.FindLast(x => x.Key == template.DataSourceKey);
//List集合数据
if (vars.DataType == DataType.List)
{
data = JSON.Deserialize<List<Dictionary<string , string>>>(vars.Value.ToString());
}
else
{
var row = JSON.Deserialize<Dictionary<string , string>>(vars.Value.ToString());
data.Add(row);
}
}
//替换变量
foreach (var row in data)
{
//是否显示标签
var _barcodeShowLabel = template.ShowLable;
//标签的内容
var _barcodeLabelontent = ReplaceArgs(template.LableContent , row , this.MaxLength , template.AlignStyle , template.FontStyle , LineStyle.);
//条码内容
var _barcodeContent = ReplaceArgs(template.Content , row , this.MaxLength , template.AlignStyle , template.FontStyle , LineStyle.);
//如果标签内容为空,视为不显示标签
if (string.IsNullOrEmpty(_barcodeLabelontent.Trim()))
{
_barcodeLabelontent = _barcodeContent.Trim();
}
//内容为空或者非数字
if (string.IsNullOrEmpty(_barcodeContent.Trim()) || !this.IsNumber(_barcodeContent.Trim()))
{
continue;
}
var content = new PrintContent();
content.Format = RowFormat.Barcode;
var sb = new StringBuilder();
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
//字体指令
sb.Append(ParseFontStyle(template.FontStyle, command));
switch (template.AlignStyle)
{
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignLeftCommand));
}
break;
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignCenterCommand));
}
break;
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignRightCommand));
}
break;
}
sb.AppendLine("");
content.Content = sb;
content.BitmapFile = BuilderBarcode(_barcodeContent.Trim() , _barcodeShowLabel , _barcodeLabelontent.Trim() , template.AlignStyle);
result.Add(content);
}
}
break;
case RowFormat.QRCode:
{
//行数据模版
var template = JSON.Deserialize<QRCodeTemplate>(rows.Template.ToString());
//数据源参数,无论单行还是列表数据源采用List方式兼容单行选择集合数据源重复行打印
var data = new List<Dictionary<string, string>>();
//包含数据源参数,重置
if (args.Exists(x => x.Key == template.DataSourceKey))
{
//当前数据源
var vars = args.FindLast(x => x.Key == template.DataSourceKey);
//List集合数据
if (vars.DataType == DataType.List)
{
data = JSON.Deserialize<List<Dictionary<string, string>>>(vars.Value.ToString());
}
else
{
var row = JSON.Deserialize<Dictionary<string, string>>(vars.Value.ToString());
data.Add(row);
}
}
//替换变量
foreach (var row in data)
{
//二维码内容
var _content = ReplaceArgs(template.Content , row , this.MaxLength , template.AlignStyle , template.FontStyle , LineStyle.);
//内容为空
if (string.IsNullOrEmpty(_content.Trim()))
{
continue;
}
var content = new PrintContent();
content.Format = RowFormat.QRCode;
var sb = new StringBuilder();
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
//字体指令
sb.Append(ParseFontStyle(template.FontStyle , command));
switch (template.AlignStyle)
{
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignLeftCommand));
}
break;
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignCenterCommand));
}
break;
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignRightCommand));
}
break;
}
sb.AppendLine("");
content.Content = sb;
content.BitmapFile = BuilderQRCode(_content,template.SizeMode);
result.Add(content);
}
}
break;
case RowFormat.Bitmap:
{
//行数据模版
var template = JSON.Deserialize<BitmapTemplate>(rows.Template.ToString());
//数据源参数,无论单行还是列表数据源采用List方式兼容单行选择集合数据源重复行打印
var data = new List<Dictionary<string , string>>();
//包含数据源参数,重置
if (args.Exists(x => x.Key == template.DataSourceKey))
{
//当前数据源
var vars = args.FindLast(x => x.Key == template.DataSourceKey);
//List集合数据
if (vars.DataType == DataType.List)
{
data = JSON.Deserialize<List<Dictionary<string , string>>>(vars.Value.ToString());
}
else
{
var row = JSON.Deserialize<Dictionary<string , string>>(vars.Value.ToString());
data.Add(row);
}
}
//替换变量
foreach (var row in data)
{
//位图路径
//var _bitmapFile = ReplaceArgs(template.Content , row , this.MaxLength , template.AlignStyle , template.FontStyle , LineStyle.不填充);
var _bitmapFile = string.Empty;
if (row.ContainsKey(template.Content))
{
_bitmapFile = row[template.Content];
}
//文件不存在
if (string.IsNullOrEmpty(_bitmapFile) || !File.Exists(_bitmapFile.Trim()))
{
continue;
}
var content = new PrintContent();
content.Format = RowFormat.Bitmap;
var sb = new StringBuilder();
//初始化
if (!isInit)
{
sb.Append(ParseEscPosCommand(command.InitCommand));
isInit = true;
}
//字体指令
sb.Append(ParseFontStyle(template.FontStyle , command));
switch (template.AlignStyle)
{
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignLeftCommand));
}
break;
case AlignStyle.:
{
//sb.Append(ParseEscPosCommand(command.AlignCenterCommand));
sb.Append(ParseEscPosCommand("27,97,1"));
}
break;
case AlignStyle.:
{
sb.Append(ParseEscPosCommand(command.AlignRightCommand));
}
break;
}
sb.AppendLine("");
content.Content = sb;
var bitmap = new Bitmap(Bitmap.FromFile(_bitmapFile.Trim()));
content.BitmapFile = ConvertToBpp(bitmap);
result.Add(content);
}
}
break;
}
}
if(footerLine > 0)
{
var _footer = new PrintContent();
_footer.Format = RowFormat.Line;
var bs = new StringBuilder();
//打印图片后不初始化,会不打印后续内容
bs.Append(ParseEscPosCommand(command.InitCommand));
//if (!isInit)
//{
// isInit = true;
//}
for (int i = 0; i < footerLine; i++)
{
bs.AppendLine("");
}
_footer.Content = bs;
_footer.AlignStyle = AlignStyle.;
_footer.FontStyle = FontStyle.;
_footer.BitmapFile = string.Empty;
result.Add(_footer);
}
//切纸指令
if (pobject.CutPager)
{
result.Add(CutPager(pobject));
}
//蜂鸣
if(pobject.Beep)
{
var content = new PrintContent();
content.Format = RowFormat.Line;
content.Content = new StringBuilder().Append(ParseEscPosCommand("27,66,3,1"));
result.Add(content);
}
return result;
}
//判断字符串是否为纯数字
public bool IsNumber(string str)
{
if (str == null || str.Length == 0)
return false;
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] bytestr = ascii.GetBytes(str);
foreach (byte c in bytestr)
{
if (c < 48 || c > 57)
{
return false;
}
}
return true;
}
public PrintContent OpenCashbox(PrinterObject pobject)
{
EscPosCommand command = pobject.EscPosCommand;
var content = new PrintContent();
content.Format = RowFormat.Line;
var sb = new StringBuilder();
//初始化
sb.Append(ParseEscPosCommand(command.InitCommand));
//开钱箱
sb.Append(ParseEscPosCommand(command.CashboxCommand));
content.Content = sb;
return content;
}
public PrintContent CutPager(PrinterObject pobject)
{
EscPosCommand command = pobject.EscPosCommand;
var content = new PrintContent();
content.Format = RowFormat.Line;
var sb = new StringBuilder();
//初始化
sb.Append(ParseEscPosCommand(command.InitCommand));
//切纸
sb.Append(ParseEscPosCommand(command.CutPageCommand));
content.Content = sb;
return content;
}
private string BuilderQRCode(string content,QRCodeSizeMode size)
{
QRCodeGenerator.ECCLevel eccLevel = QRCodeGenerator.ECCLevel.Q;
using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
{
using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(content , eccLevel))
{
using (QRCode qrCode = new QRCode(qrCodeData))
{
Bitmap bitmap = null;
switch (size)
{
case QRCodeSizeMode.:
{
bitmap = qrCode.GetGraphic(10 , Color.Black , Color.White , false);
}
break;
case QRCodeSizeMode.:
{
bitmap = qrCode.GetGraphic(5 , Color.Black , Color.White , false);
}
break;
case QRCodeSizeMode.:
default:
{
bitmap = qrCode.GetGraphic(8 , Color.Black , Color.White , false);
}
break;
}
return ConvertToBpp(bitmap);
}
}
}
}
private string BuilderBarcode(string content, bool showLabel , string lableContent, AlignStyle align)
{
Barcode barcode = new Barcode();
barcode.IncludeLabel = showLabel;
barcode.LabelFont = new Font("Microsoft Sans Serif" , 15.75F , System.Drawing.FontStyle.Bold);
barcode.AlternateLabel = lableContent;
barcode.Height = 90;
barcode.Width = Convert.ToInt16(45 * 8);
switch (align)
{
case AlignStyle.:
{
barcode.Alignment = AlignmentPositions.LEFT;
barcode.LabelPosition = LabelPositions.BOTTOMLEFT;
}
break;
case AlignStyle.:
{
barcode.Alignment = AlignmentPositions.CENTER;
barcode.LabelPosition = LabelPositions.BOTTOMCENTER;
}
break;
case AlignStyle.:
{
barcode.Alignment = AlignmentPositions.RIGHT;
barcode.LabelPosition = LabelPositions.BOTTOMRIGHT;
}
break;
}
barcode.ImageFormat = ImageFormat.Bmp;
var bitmap = new Bitmap(barcode.Encode(TYPE.CODE128 , content));
return ConvertToBpp(bitmap);
}
/// <summary>
/// 转换单色位图的方法
/// </summary>
/// <param name="img"></param>
private Bitmap xxx(Bitmap img)
{
int w = img.Width;
int h = img.Height;
Bitmap bmp = new Bitmap(w , h , PixelFormat.Format1bppIndexed);
BitmapData data = bmp.LockBits(new Rectangle(0 , 0 , w , h) , ImageLockMode.ReadWrite , PixelFormat.Format1bppIndexed);
for (int y = 0; y < h; y++)
{
byte[] scan = new byte[(w + 7) / 8];
for (int x = 0; x < w; x++)
{
Color c = img.GetPixel(x , y);
if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
}
Marshal.Copy(scan , 0 , (IntPtr)((int)data.Scan0 + data.Stride * y) , scan.Length);
}
bmp.Palette = CreateGrayscalePalette();
return bmp;
}
/// <summary>
/// 创建单色灰度调色板
/// </summary>
/// <returns>返回调色板</returns>
private ColorPalette CreateGrayscalePalette()
{
ColorPalette palette = CreateColorPalette(PixelFormat.Format1bppIndexed);
palette.Entries[0] = Color.FromArgb(0 , 0 , 0 , 0);
palette.Entries[1] = Color.FromArgb(0 , 255 , 255 , 255);
return palette;
}
/// <summary>
/// 创建图像格式对应的调色板
/// </summary>
/// <param name="pixelFormat">图像格式只能是Format1bppIndexed,Format1bppIndexed,Format1bppIndexed</param>
/// <returns>返回调色板如果创建失败或者图像格式不支持返回null。</returns>
private ColorPalette CreateColorPalette(PixelFormat pixelFormat)
{
ColorPalette palette = null;
if (pixelFormat == PixelFormat.Format1bppIndexed || pixelFormat == PixelFormat.Format4bppIndexed || pixelFormat == PixelFormat.Format8bppIndexed)
{
//因为ColorPalette类没有构造函数所以这里创建一个1x1的位图然后抓取该位图的调色板
Bitmap temp = new Bitmap(1 , 1 , pixelFormat);
palette = temp.Palette;
temp.Dispose();
}
return palette;
}
/// <summary>
/// 转换为单色位图后图像信息头中的位图使用的颜色数及指定重要的颜色数设置为0
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
private string ConvertToBpp(Bitmap bitMap)
{
//打开任一索引色的或者非索引色的图像
Bitmap bm = xxx(bitMap);
MemoryStream ms = new MemoryStream();
bm.Save(ms , System.Drawing.Imaging.ImageFormat.Bmp);
byte[] buffer = new byte[ms.Length];
//Image.Save()会改变MemoryStream的Position需要重新Seek到Begin
ms.Seek(0 , SeekOrigin.Begin);
ms.Read(buffer , 0 , buffer.Length);
byte[] bitLenght = new byte[4];
Array.Copy(buffer , 2 , bitLenght , 0 , 4);
int ibitlen = BytesToInt(bitLenght , 0);
Array.Copy(bitLenght , 0 , buffer , 34 , 4);
byte[] bitmapBuffer = new byte[1];
bitmapBuffer[0] = 0;
Array.Copy(bitmapBuffer , 0 , buffer , 46 , 1);
Array.Copy(bitmapBuffer , 0 , buffer , 50 , 1);
FileStream fs = null;
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory , @"temp\");
if (!Directory.Exists(basePath))
{
Directory.CreateDirectory(basePath);
}
string filename = DesignerObjectId.GenerateNewStringId() + ".bmp";
string file = Path.Combine(basePath,filename);
//将待写的入数据从字符串转换为字节数组
fs = File.OpenWrite(file);
//设定书写的开始位置为文件的末尾
fs.Position = 0;//fs.Length
//将待写入内容追加到文件末尾
fs.Write(buffer , 0 , ibitlen);
fs.Close();
bm.Dispose();
return file;
}
private int BytesToInt(byte[] ary , int offset)
{
int value;
value = (int)((ary[offset] & 0xFF) | ((ary[offset + 1] << 8) & 0xFF00) | ((ary[offset + 2] << 16) & 0xFF0000) | ((ary[offset + 3] << 24) & 0xFF000000));
return value;
}
///// <summary>
///// 构建打印字符串
///// </summary>
///// <param name="pobject">打印对象</param>
///// <param name="args">模版参数</param>
///// <param name="isOpenCashbox">是否打开钱箱</param>
///// <param name="isCutPage">是否切纸</param>
///// <param name="isPreview">是否生成预览文件</param>
///// <returns></returns>
//public StringBuilder Parse(PrinterObject pobject , List<VariableValue> args , bool isPreview)
//{
// if (pobject == null)
// {
// pobject = new PrinterObject();
// }
// if (args == null)
// {
// args = new List<VariableValue>();
// }
// EscPosCommand command = pobject.EscPosCommand;
// StringBuilder sb = new StringBuilder();
// //初始化指令
// if (!isPreview)
// {
// sb.Append(ParseEscPosCommand(command.InitCommand));
// //钱箱指令
// if (pobject.OpenCashbox)
// {
// sb.Append(ParseEscPosCommand(command.CashboxCommand));
// }
// }
// foreach (var rows in this.Rows)
// {
// switch (rows.RowFormat)
// {
// case RowFormat.Line:
// {
// //行数据模版
// var template = JSON.Deserialize<LineTemplate>(rows.Template.ToString());
// //数据源参数,无论单行还是列表数据源采用List方式兼容单行选择集合数据源重复行打印
// var data = new List<Dictionary<string , string>>();
// //包含数据源参数,重置
// if (args.Exists(x=>x.Key == template.DataSourceKey))
// {
// //当前数据源
// var vars = args.FindLast(x=>x.Key == template.DataSourceKey);
// //List集合数据
// if (vars.DataType == DataType.List)
// {
// data = JSON.Deserialize<List<Dictionary<string , string>>>(vars.Value.ToString());
// }
// else
// {
// var row = JSON.Deserialize<Dictionary<string , string>>(vars.Value.ToString());
// data.Add(row);
// }
// }
// //替换变量
// foreach(var row in data)
// {
// //字体指令
// if (isPreview)
// {
// sb.Append((int)template.FontStyle + ",");
// }
// else
// {
// sb.Append(ParseFontStyle(template.FontStyle , command));
// }
// sb.AppendLine(ReplaceArgs(template.Content , row , this.MaxLength , template.AlignStyle , template.FontStyle , template.LineStyle));
// }
// }
// break;
// case RowFormat.Column:
// {
// var template = JSON.Deserialize<List<LineTemplate>>(rows.Template.ToString());
// var result = MergeLineTemplate(template[0] , template[1] , args , command);
// foreach (var str in result)
// {
// sb.Append(str);
// }
// }
// break;
// case RowFormat.Grid:
// {
// var template = JSON.Deserialize<GridTemplate>(rows.Template.ToString());
// //数据源参数,必须为列表
// var data = new List<Dictionary<string , string>>();
// //包含数据源参数,重置
// if (args.Exists(x => x.Key == template.DataSourceKey))
// {
// //当前数据源
// var vars = args.FindLast(x => x.Key == template.DataSourceKey);
// //List集合数据
// if (vars.DataType == DataType.List)
// {
// data = JSON.Deserialize<List<Dictionary<string, string>>>(vars.Value.ToString());
// }
// else
// {
// var row = JSON.Deserialize<Dictionary<string, string>>(vars.Value.ToString());
// data.Add(row);
// }
// }
// //判断是否符合打印条件
// var notAllowEmpty = template.NotAllowEmpty;
// if (notAllowEmpty && data.Count == 0)
// {
// continue;
// }
// //字体指令
// if (isPreview)
// {
// sb.Append((int)template.FontStyle + ",");
// }
// else
// {
// sb.Append(ParseFontStyle(template.FontStyle, command));
// }
// //标题行添加下划线
// string paddingChar = this.ParseLineType(template.LineStyle);
// var _columnWidth = new Dictionary<int , int>();
// int _column = 0;
// int _sum = 0;
// foreach (ColumnTempate col in template.Columns)
// {
// _sum += col.Length;
// _columnWidth.Add(_column++ , _sum);
// var title = ReplaceArgs(col.Name , null , col.Length , col.AlignStyle , template.FontStyle , LineStyle.不填充);
// int titleLength = GetPrintStringLength(title);
// int titleDiff = col.Length - titleLength;
// sb.Append(title + ("".PadRight(titleDiff < 0 ? 0 : titleDiff , Convert.ToChar(paddingChar))));
// }
// //提交标题行打印
// sb.AppendLine("");
// //提交下划线打印
// if (!string.IsNullOrEmpty(paddingChar.Trim()))
// {
// //字体指令
// if (isPreview)
// {
// sb.Append((int)FontStyle.正常字体 + ",");
// }
// else
// {
// sb.Append(ParseFontStyle(FontStyle.正常字体, command));
// }
// sb.AppendLine("".PadRight(this.MaxLength , Convert.ToChar(paddingChar)));
// }
// //模版数据
// for (int row = 0; row < data.Count; row++)
// {
// //判断是否允许输出合计行,并且是最后一行
// if(template.ContainsTotalRow && row + 1 == data.Count)
// {
// //不允许打印,结束本次循环
// if (!template.OutputTotalRow)
// {
// continue;
// }
// //字体指令
// if (isPreview)
// {
// sb.Append((int)FontStyle.正常字体 + ",");
// }
// else
// {
// sb.Append(ParseFontStyle(FontStyle.正常字体, command));
// }
// sb.AppendLine("".PadRight(this.MaxLength , Convert.ToChar(paddingChar)));
// }
// //字体指令
// if (isPreview)
// {
// sb.Append((int)template.FontStyle + ",");
// }
// else
// {
// sb.Append(ParseFontStyle(template.FontStyle, command));
// }
// int cols = 0;
// var _offset = new Dictionary<int,int>();
// foreach (ColumnTempate col in template.Columns)
// {
// if (template.AllowNewLine)
// {
// var content = ReplaceArgs(col.DataMember , template.AllowNewLine , data[row] , col.Length , col.AlignStyle , template.FontStyle , LineStyle.不填充);
// int len = GetPrintStringLength(content);
// //长度超出,允许独占一行
// if (len > col.Length)
// {
// _offset[cols] = _columnWidth[cols];
// }
// else
// {
// _offset[cols] = 0;
// }
// if (_offset[cols] > 0)
// {
// int width = cols == 0 ? 0 : _offset[cols - 1];
// sb.AppendLine("".PadLeft(width , ' ') + content);
// }
// else
// {
// int width = cols == 0 ? 0 : _offset[cols - 1];
// sb.Append("".PadLeft(width , ' '));
// int diff = col.Length - len;
// sb.Append(content + ("".PadRight(diff < 0 ? 0 : diff , ' ')));
// }
// }
// else
// {
// var content = ReplaceArgs(col.DataMember , template.AllowNewLine , data[row] , col.Length , col.AlignStyle , template.FontStyle , LineStyle.不填充);
// int len = GetPrintStringLength(content);
// int diff = col.Length - len;
// sb.Append(content + ("".PadRight(diff < 0 ? 0 : diff , ' ')));
// }
// cols++;
// }
// sb.AppendLine("");
// }
// }
// break;
// }
// }
// //归位打印机字体
// if (!isPreview)
// {
// sb.Append(ParseEscPosCommand(command.NormalCommand));
// }
// //切纸指令
// if (!isPreview && pobject.CutPager)
// {
// sb.Append(ParseEscPosCommand(command.CutPageCommand));
// }
// //提交
// if (!isPreview)
// {
// sb.AppendLine("");
// }
// return sb;
//}
/// <summary>
/// 表格超出打印宽度特殊处理
/// </summary>
/// <param name="content"></param>
/// <param name="fullLine"></param>
/// <param name="args"></param>
/// <param name="maxLength"></param>
/// <param name="alignStyle"></param>
/// <param name="fontStyle"></param>
/// <param name="lineStyle"></param>
/// <returns></returns>
private string ReplaceArgs(string content ,bool fullLine, Dictionary<string , string> args , int maxLength , AlignStyle alignStyle , FontStyle fontStyle , LineStyle lineStyle)
{
if (args == null)
{
args = new Dictionary<string , string>();
}
foreach (var item in args)
{
var match = item.Key;
var regex = new Regex(match , RegexOptions.IgnoreCase);
if (item.Value is string)
{
content = regex.Replace(content , item.Value.ToString());
}
}
Tuple<int , List<string>> res = GetPrintStringLength(content , fullLine , maxLength , fontStyle);
int length = res.Item1;
List<string> str = res.Item2;
string result = string.Empty;
for (int i = 0; i < str.Count; i++)
{
var s = str[i];
int len = GetPrintStringLength(s , fontStyle);
int fix = 0;
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
fix = 2;
break;
case FontStyle.:
case FontStyle.:
fix = 4;
break;
default:
fix = 2;
break;
}
int diff = 0;
string paddingChar = this.ParseLineType(lineStyle);
switch (alignStyle)
{
case AlignStyle.:
diff = (maxLength - len) / fix * 2;
result += s + "".PadRight(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar));
break;
case AlignStyle.:
diff = (maxLength - len) / fix;
result += "".PadLeft(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar)) + s + "".PadRight(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar));
break;
case AlignStyle.:
diff = (maxLength - len) / fix * 2;
result += "".PadLeft(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar)) + s;
break;
}
if (i + 1 != str.Count)
{
result += Environment.NewLine;
}
}
//处理单独划线
if (string.IsNullOrEmpty(result))
{
int fix = 0;
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
fix = 2;
break;
case FontStyle.:
case FontStyle.:
fix = 4;
break;
default:
fix = 2;
break;
}
string paddingChar = this.ParseLineType(lineStyle);
result = "".PadRight(maxLength / fix * 2 , Convert.ToChar(paddingChar));
}
return result;
}
/// <summary>
/// 表格超出打印宽度特殊处理
/// </summary>
/// <param name="str"></param>
/// <param name="fullLine"></param>
/// <param name="maxLength"></param>
/// <param name="fontStyle"></param>
/// <returns></returns>
private Tuple<int , List<string>> GetPrintStringLength(string str , bool fullLine , int maxLength , FontStyle fontStyle)
{
int valueLength = 0;
List<string> list = new List<string>();
string tmpString = "";
string chinese = @"^[\u0391-\uFFE5]+$";
// 获取字段值的长度如果含中文字符则每个中文字符长度为2否则为1
for (int i = 0; i < str.Length; i++)
{
// 获取一个字符
string temp = str[i].ToString();
// 判断是否为中文字符
if (Regex.IsMatch(temp , chinese))
{
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
valueLength += 2;
break;
case FontStyle.:
case FontStyle.:
valueLength += 4;
break;
default:
valueLength += 2;
break;
}
}
else
{
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
valueLength += 1;
break;
case FontStyle.:
case FontStyle.:
valueLength += 2;
break;
default:
valueLength += 1;
break;
}
}
tmpString += temp;
if (!fullLine)
{
if (valueLength % maxLength == 0)
{
list.Add(tmpString);
tmpString = "";
}
}
}
if (!string.IsNullOrEmpty(tmpString))
{
list.Add(tmpString);
}
// 进位取整
return new Tuple<int , List<string>>(valueLength , list);
}
/// <summary>
/// 合并两列布局的数据为行数据
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <param name="args"></param>
/// <param name="command"></param>
/// <returns></returns>
public List<string> MergeLineTemplate(LineTemplate left , LineTemplate right , List<VariableValue> args , EscPosCommand command)
{
//数据源参数
var data = new List<Dictionary<string, string>>();
//包含数据源参数,重置
if (args.Exists(x => x.Key == left.DataSourceKey))
{
//当前数据源
var vars = args.FindLast(x => x.Key == left.DataSourceKey);
//List集合数据
if (vars.DataType == DataType.List)
{
data = JSON.Deserialize<List<Dictionary<string, string>>>(vars.Value.ToString());
}
else
{
var row = JSON.Deserialize<Dictionary<string, string>>(vars.Value.ToString());
data.Add(row);
}
}
//左标签的换行后字符串列表
List<string> leftList = ReplaceArgsEx(left.Content , data , left.Length , left.AlignStyle , left.FontStyle , left.LineStyle);
var leftDictionary = new Dictionary<int,string>();
for(int i = 0; i < leftList.Count; i++)
{
leftDictionary.Add(i , leftList[i]);
}
//重置
data = new List<Dictionary<string , string>>();
//包含数据源参数,重置
if (args.Exists(x => x.Key == right.DataSourceKey))
{
//当前数据源
var vars = args.FindLast(x => x.Key == right.DataSourceKey);
//List集合数据
if (vars.DataType == DataType.List)
{
data = JSON.Deserialize<List<Dictionary<string, string>>>(vars.Value.ToString());
}
else
{
var row = JSON.Deserialize<Dictionary<string, string>>(vars.Value.ToString());
data.Add(row);
}
}
//右标签的换行后字符串列表
List<string> rightList = ReplaceArgsEx(right.Content , data , right.Length , right.AlignStyle , right.FontStyle , right.LineStyle);
var rightDictionary = new Dictionary<int , string>();
for (int i = 0; i < rightList.Count; i++)
{
rightDictionary.Add(i , rightList[i]);
}
var result = new List<string>();
var diff = leftList.Count - rightList.Count;
if (diff>0)
{
for(int i = 0; i < diff; i++)
{
rightList.Insert(0 , "");
}
}
else
{
for (int i = 0; i < Math.Abs(diff); i++)
{
leftList.Insert(0 , "");
}
}
for (int i = 0; i < leftList.Count; i++)
{
StringBuilder sb = new StringBuilder();
//字体指令
sb.Append(ParseFontStyle(left.FontStyle , command));
sb.Append(leftList[i]);
sb.Append(rightList[i]);
result.Add(sb.ToString());
}
return result;
}
public List<string> ReplaceArgsEx(string content , List<Dictionary<string, string>> args , int maxLength , AlignStyle alignStyle , FontStyle fontStyle , LineStyle lineStyle)
{
List<string> result = new List<string>();
foreach(var data in args)
{
string str = ReplaceArgs(content , data , maxLength , alignStyle , fontStyle , lineStyle);
if (str.Contains(Environment.NewLine))
{
string[] array = str.Split(new string[] { Environment.NewLine } , StringSplitOptions.RemoveEmptyEntries);
result.AddRange(array);
}
else
{
string paddingChar = this.ParseLineType(lineStyle);
if (string.IsNullOrEmpty(str))
{
str = "".PadLeft(maxLength , Convert.ToChar(paddingChar));
}
result.Add(str);
}
}
return result;
}
private string ReplaceArgs(string content , Dictionary<string , string> args , int maxLength , AlignStyle alignStyle , FontStyle fontStyle,LineStyle lineStyle)
{
if (args == null)
{
args = new Dictionary<string , string>();
}
foreach (var item in args)
{
var match = item.Key;
var regex = new Regex(match , RegexOptions.IgnoreCase);
if (item.Value is string)
{
content = regex.Replace(content , item.Value.ToString());
}
}
Tuple<int , List<string>> res = GetPrintStringLength(content , maxLength , fontStyle);
int length = res.Item1;
List<string> str = res.Item2;
string result = string.Empty;
for (int i = 0; i < str.Count; i++)
{
var s = str[i];
int len = GetPrintStringLength(s , fontStyle);
int fix = 0;
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
fix = 2;
break;
case FontStyle.:
case FontStyle.:
fix = 4;
break;
default:
fix = 2;
break;
}
int diff = 0;
string paddingChar = this.ParseLineType(lineStyle);
switch (alignStyle)
{
case AlignStyle.:
diff = (maxLength - len) * 2 / fix;
result += s + "".PadRight(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar));
break;
case AlignStyle.:
diff = (maxLength - len) / fix;
result += "".PadLeft(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar)) + s + "".PadRight(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar));
break;
case AlignStyle.:
diff = (maxLength - len) * 2 / fix;
result += "".PadLeft(diff < 0 ? 0 : diff , Convert.ToChar(paddingChar)) + s;
break;
}
if (i + 1 != str.Count)
{
result += Environment.NewLine;
}
}
//处理单独划线
if (string.IsNullOrEmpty(result))
{
int fix = 0;
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
fix = 2;
break;
case FontStyle.:
case FontStyle.:
fix = 4;
break;
default:
fix = 2;
break;
}
string paddingChar = this.ParseLineType(lineStyle);
result = "".PadRight(maxLength * 2 / fix , Convert.ToChar(paddingChar));
}
return result;
}
private static int GetPrintStringLength(string str , FontStyle fontStyle)
{
int valueLength = 0;
string chinese = @"^[\u0391-\uFFE5]+$";
// 获取字段值的长度如果含中文字符则每个中文字符长度为2否则为1
for (int i = 0; i < str.Length; i++)
{
// 获取一个字符
string temp = str[i].ToString();
// 判断是否为中文字符
if (Regex.IsMatch(temp , chinese))
{
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
valueLength += 2;
break;
case FontStyle.:
case FontStyle.:
valueLength += 4;
break;
default:
valueLength += 2;
break;
}
}
else
{
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
valueLength += 1;
break;
case FontStyle.:
case FontStyle.:
valueLength += 2;
break;
default:
valueLength += 1;
break;
}
}
}
// 进位取整
return valueLength;
}
private Tuple<int , List<string>> GetPrintStringLength(string str , int maxLength , FontStyle fontStyle)
{
int valueLength = 0;
List<string> list = new List<string>();
string tmpString = "";
string chinese = @"^[\u0391-\uFFE5]+$";
// 获取字段值的长度如果含中文字符则每个中文字符长度为2否则为1
for (int i = 0; i < str.Length; i++)
{
// 获取一个字符
string temp = str[i].ToString();
// 判断是否为中文字符
if (Regex.IsMatch(temp , chinese))
{
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
valueLength += 2;
break;
case FontStyle.:
case FontStyle.:
valueLength += 4;
break;
default:
valueLength += 2;
break;
}
}
else
{
switch (fontStyle)
{
case FontStyle.:
case FontStyle.:
valueLength += 1;
break;
case FontStyle.:
case FontStyle.:
valueLength += 2;
break;
default:
valueLength += 1;
break;
}
}
tmpString += temp;
if (valueLength >= this.MaxLength)
{
list.Add(tmpString);
tmpString = "";
valueLength = 0;
}
}
if (!string.IsNullOrEmpty(tmpString))
{
list.Add(tmpString);
}
// 进位取整
return new Tuple<int , List<string>>(valueLength , list);
}
private string ParseEscPosCommand(string command)
{
string[] array = command.Split(',');
List<byte> bytList = new List<byte>();
foreach (var s in array)
{
bytList.Add(Convert.ToByte(s.Trim()));
}
return Encoding.Default.GetString(bytList.ToArray());
}
private string ParseLineType(LineStyle lineStyle)
{
string line = " ";
switch (lineStyle)
{
case LineStyle.:
{
line = " ";
}
break;
case LineStyle.线:
{
line = "-";
}
break;
case LineStyle.线:
{
line = "=";
}
break;
case LineStyle.线:
{
line = "#";
}
break;
case LineStyle.线:
{
line = "+";
}
break;
case LineStyle.线:
{
line = "*";
}
break;
case LineStyle.线:
{
line = "_";
}
break;
}
return line;
}
private string ParseFontStyle(FontStyle fontStyle , EscPosCommand command)
{
string result = ParseEscPosCommand(command.NormalCommand);
//27 , 33 , 48 (0,16,32,48)
//28 , 33 , 12 04812
switch (fontStyle)
{
case FontStyle.:
result = ParseEscPosCommand(command.NormalCommand);
break;
case FontStyle.:
result = ParseEscPosCommand(command.DoubleWidthCommand);
break;
case FontStyle.:
result = ParseEscPosCommand(command.DoubleHeightCommand);
break;
case FontStyle.:
result = ParseEscPosCommand(command.DoubleWidthHeightCommand);
break;
}
return result;
}
}
/// <summary>
/// 位图打印模版
/// </summary>
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class BitmapTemplate
{
/// <summary>
/// 数据源
/// </summary>
[JsonProperty(PropertyName = "data")]
public string DataSourceKey { get; set; }
/// <summary>
/// 字体格式
/// </summary>
[JsonProperty(PropertyName = "font")]
public FontStyle FontStyle { get; set; }
/// <summary>
/// 对齐格式
/// </summary>
[JsonProperty(PropertyName = "align")]
public AlignStyle AlignStyle { get; set; }
/// <summary>
/// 位图路径
/// </summary>
[JsonProperty(PropertyName = "content")]
public string Content { get; set; }
/// <summary>
/// 字符串长度
/// </summary>
[JsonProperty(PropertyName = "length")]
public int Length { get; set; }
}
/// <summary>
/// 二维码打印模版
/// </summary>
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class QRCodeTemplate
{
/// <summary>
/// 数据源
/// </summary>
[JsonProperty(PropertyName = "data")]
public string DataSourceKey { get; set; }
/// <summary>
/// 字体格式
/// </summary>
[JsonProperty(PropertyName = "font")]
public FontStyle FontStyle { get; set; }
/// <summary>
/// 对齐格式
/// </summary>
[JsonProperty(PropertyName = "align")]
public AlignStyle AlignStyle { get; set; }
/// <summary>
/// 二维码大小
/// </summary>
[JsonProperty(PropertyName = "size")]
public QRCodeSizeMode SizeMode { get; set; }
/// <summary>
/// 条码标签生成内容
/// </summary>
[JsonProperty(PropertyName = "content")]
public string Content { get; set; }
/// <summary>
/// 字符串长度
/// </summary>
[JsonProperty(PropertyName = "length")]
public int Length { get; set; }
}
/// <summary>
/// 条码打印模版
/// </summary>
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class BarcodeTemplate
{
/// <summary>
/// 数据源
/// </summary>
[JsonProperty(PropertyName = "data")]
public string DataSourceKey { get; set; }
/// <summary>
/// 字体格式
/// </summary>
[JsonProperty(PropertyName = "font")]
public FontStyle FontStyle { get; set; }
/// <summary>
/// 对齐格式
/// </summary>
[JsonProperty(PropertyName = "align")]
public AlignStyle AlignStyle { get; set; }
/// <summary>
/// 条码标签生成内容
/// </summary>
[JsonProperty(PropertyName = "content")]
public string Content { get; set; }
/// <summary>
/// 字符串长度
/// </summary>
[JsonProperty(PropertyName = "length")]
public int Length { get; set; }
/// <summary>
/// 是否显示条码标签
/// </summary>
[JsonProperty(PropertyName = "showLable")]
public bool ShowLable { get; set; } = false;
/// <summary>
/// 条码标签生成内容
/// </summary>
[JsonProperty(PropertyName = "lableContent")]
public string LableContent { get; set; }
}
/// <summary>
/// 行打印模版,单行和两列控件依赖
/// </summary>
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class LineTemplate
{
/// <summary>
/// 数据源
/// </summary>
[JsonProperty(PropertyName = "data")]
public string DataSourceKey { get; set; }
/// <summary>
/// 字体格式
/// </summary>
[JsonProperty(PropertyName = "font")]
public FontStyle FontStyle { get; set; }
/// <summary>
/// 填充线条,主要解决划线
/// </summary>
[JsonProperty(PropertyName = "line")]
public LineStyle LineStyle { get; set; }
/// <summary>
/// 对齐格式
/// </summary>
[JsonProperty(PropertyName = "align")]
public AlignStyle AlignStyle { get; set; }
/// <summary>
/// 包含变量格式的内容
/// </summary>
[JsonProperty(PropertyName = "content")]
public string Content { get; set; }
/// <summary>
/// 字符串长度
/// </summary>
[JsonProperty(PropertyName = "length")]
public int Length { get; set; }
}
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class RowTemplate
{
/// <summary>
/// 行数据格式
/// </summary>
[JsonProperty(PropertyName = "format")]
public RowFormat RowFormat { get; set; }
/// <summary>
///
/// </summary>
[JsonProperty(PropertyName = "template")]
public object Template { get; set; }
}
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class GridTemplate
{
[JsonProperty(PropertyName = "data")]
public string DataSourceKey { get; set; }
private List<ColumnTempate> _columns = new List<ColumnTempate>();
[JsonProperty(PropertyName = "columns")]
public List<ColumnTempate> Columns
{
get
{
return _columns;
}
}
public void AddColumn(ColumnTempate column)
{
this.Columns.Add(column);
}
/// <summary>
/// 表头下划线格式
/// </summary>
[JsonProperty(PropertyName = "line")]
public LineStyle LineStyle { get; set; }
/// <summary>
/// 表格的字体
/// </summary>
[JsonProperty(PropertyName = "font")]
public FontStyle FontStyle { get; set; }
/// <summary>
/// 是否包含合计行
/// </summary>
[JsonProperty(PropertyName = "contains")]
public bool ContainsTotalRow { get; set; }
/// <summary>
/// 是否输出打印合计行
/// </summary>
[JsonProperty(PropertyName = "output")]
public bool OutputTotalRow { get; set; }
/// <summary>
/// 超出打印字符长度,独占一行
/// </summary>
[JsonProperty(PropertyName = "newline")]
public bool AllowNewLine { get; set; }
/// <summary>
/// 如果记录集为空不打印
/// </summary>
[JsonProperty(PropertyName = "empty")]
public bool NotAllowEmpty { get; set; }
/// <summary>
/// 禁止打印表头
/// </summary>
[JsonProperty(PropertyName = "header")]
public bool NotAllowHeader { get; set; } = false;
/// <summary>
/// 表头采用正常字体打印
/// </summary>
[JsonProperty(PropertyName = "headerFont")]
public bool HeaderFontStyle { get; set; } = false;
}
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class ColumnTempate
{
public ColumnTempate(string name , AlignStyle alignStyle , string dataMember , int length)
{
this.Name = name;
this.AlignStyle = alignStyle;
this.DataMember = dataMember;
this.Length = length;
}
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "align")]
public AlignStyle AlignStyle { get; set; }
[JsonProperty(PropertyName = "vars")]
public string DataMember { get; set; }
[JsonProperty(PropertyName = "length")]
public int Length { get; set; }
}
}