|
|
|
|
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 (0,4,8,12 )
|
|
|
|
|
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; }
|
|
|
|
|
}
|
|
|
|
|
}
|