本篇适用于复杂的动态模板打印,即不同业务+对应的数据源(单据设计)才能实现,如果是单个页面的打印,建议使用在页面使用ADD_PRINT_HTM(intTop,intLeft,intWidth,intHeight,strHtml)来实现功能 这个超级简单,strHtml就是用Js获取的打印内容的Html
=====================================================================
公司的任务:用一个打印插件将所有的业务的单据做成打印模板
最终确定使用Lodop 功能的确强大
Lodop和以往的Js插件不一样,如果项目着急上线会get不到他的强大,废话不多说,上干货
首先,我还是建议大家看看官网的在线样例http://www.lodop.net/
文章最后贴了部分代码 新手估计看不动 个人只是笔记记录 有需要可以联系我
【经验所得】
1模板中参数怎么赋值 1.在前端输出模板内容后,用lodop语法重新赋值 2在后端将模板中参数进行替换,在前端直接输出
一开始纠结怎么把模板中的参数进行替换,是在前端进行用代码重新赋值,还是在后端把模板中参数进行替换,最终经过考量使用后端方案,也是我比较建议的,特别适合复杂情况的单据
2模板内容在前端是当作js执行的,而我们一般要读取数据库再放到页面 需要使用js函数 eval()
eval('模板内容');
3表格打印的适合 如果内容过多 如果设置不正确 不会全部打印
模板效果
配置界面设计
文本框动态参数配置
表格动态参数配置
预览效果
部分代码实例
LODOP = getLodop();
var text = $("#<%=txt_TemplateText.ClientID%>").val();
eval(text);
if (LODOP.CVERSION) CLODOP.On_Return = function (TaskID, Value) { document.getElementById('<%=txt_TemplateText.ClientID%>').value = Value; };
document.getElementById('<%=txt_TemplateText.ClientID%>').value = LODOP.PRINT_DESIGN();//关闭插件编辑框后 代码自动到输入框或者自己想要绑定的地方
StringBuilder sb = new StringBuilder();
var model = sysPrintTemplateBLL.GetModel(Id);
if (model == null)
{
var resultObjError = new
{
code = -1,
content = "未找到打印模板"
};
context.Response.Write(JsonConvert.SerializeObject(resultObjError));
context.Response.End();
}
Regex strRegex = new Regex("LODOP.*\\([\\s\\S]*?\\)");
var strRegexValue = strRegex.Matches(model.TemplateText);
var itemslist = sysPrintTemplateItemsBLL.GetList(string.Format("IsLock=1 and SysPrintTemplateId='{0}'", Id));
List datasource = new List();
if (itemslist != null && itemslist.Count > 0)
{
foreach (var item in itemslist)
{
if (string.IsNullOrEmpty(item.BillEntityId)) continue;
//根据单据实体 向单据设计接口获取数据
string sqlFilter = string.Empty;
if (item.ChkUseStrWhere == 1)
{
sqlFilter = item.StrWhere;
if (sqlFilter.Contains("{Id}"))
{
sqlFilter = sqlFilter.Replace("{Id}", sqlId);
}
if (sqlFilter.Contains("{ParentId}"))
{
sqlFilter = sqlFilter.Replace("{ParentId}", sqlId);
}
}
else
{
sqlFilter = sqlWhere;
}
var data = BaseData.GetEntityDataSource(item.BillEntityId, sqlFilter, item.OrderByFields);
datasource.Add(data);
}
}
else
{
context.Response.Write(JsonConvert.SerializeObject(new { code = -1, content = "未匹配到数据源设置" }));
context.Response.End();
}
Regex regex = new Regex("\"(.+)\"");//正则 获取双引号中内容
Regex tblRegex = new Regex(@"[\s\S]*?");
Regex tdRegex = new Regex(@"[\s\S]*?");
Regex tdContentRegex = new Regex(@">\S\w*?<");
//Lodop 可以直接在LODOP.ADD_PRINT_TEXTA()将值代入,也可以用LODOP.SET_PRINT_STYLEA重新赋值
//由于我们是动态生成的模板,我们直接遍历 根据配置参数赋值
sb.AppendFormat(string.Format("LODOP.PRINT_INIT(\"{0}\");", model.Name));
sb.Append("LODOP.SET_PRINT_MODE(\"PROGRAM_CONTENT_BYVAR\",true);");
if (strRegexValue != null && strRegexValue.Count > 0)
{
for (int k = 0; k < strRegexValue.Count; k++)
{
var str = strRegexValue[k].Value;
if (string.IsNullOrEmpty(str)) continue;
if (str.Contains("LODOP.ADD_PRINT_TEXTA"))
{
#region 处理控件
//理论上只能匹配到2个值 LODOP.ADD_PRINT_TEXTA("Obj.Code",12,77,100,20,"001");
var matchContent = regex.Match(str);//获取到的是"Obj.Code",12,77,100,20,"001"
if (matchContent == null)
{
sb.AppendFormat(string.Format("{0};", str));
continue;
}
var arrayData = matchContent.Value.Split(',');
var strStart = arrayData[0].Replace("\"", "");
var strReplace = arrayData.LastOrDefault().Replace("\"", "");
//注: name[0]标准值应该是 数据标识_字段名称
var nameArray = strStart.Split('_');
if (nameArray.Length != 2)
{
sb.AppendFormat(string.Format("{0};", str));
continue;
}
//根据values[0]找到数据源
var i = 0;
object newValue = null;
bool IsMatch = false;//是否匹配到数据 如果没有则返回原文
foreach (var item in itemslist)
{
if (nameArray[0].Equals(item.DataSourceFlag))
{
//已匹配大数据源
var dt = datasource[i];
if (dt == null || dt.Rows.Count < 1) break;
//根据反射找到数据值
var objectName = nameArray[1];
var dr = dt.Rows[0];
try
{
if (dr[objectName] != null)
{
if (objectName.Contains("Date"))
{
newValue = Convert.ToDateTime(dr[objectName]).ToString("yyyy-MM-dd");
}
else if (objectName.Contains("Amount") || objectName.Contains("Money"))
{
newValue = Convert.ToDecimal(dr[objectName]).ToString("0.####");
}
else
{
newValue = dr[objectName];
}
IsMatch = true;
}
}
catch
{
}
break;
}
i++;
}
if (IsMatch)
{
//替换值
var newStr = str.Replace(strReplace, newValue.ToString());
sb.AppendFormat(string.Format("{0};", newStr));
}
else
{
sb.AppendFormat(string.Format("{0};", str));
}
#endregion
}
else if (str.Contains("LODOP.ADD_PRINT_TABLE"))
{
#region 处理表格
//理论上只能匹配到1个值 LODOP.ADD_PRINT_TABLE(26, 21, 726, 100, "表格内容");
var matchContent = regex.Match(str);
var tableHtml = matchContent.Value;
tableHtml = tableHtml.Replace("\r\n", "");
var tableText = tblRegex.Match(tableHtml);
if (tableText == null) { sb.AppendFormat(string.Format("{0};", str)); continue; }
string newTblText = new Regex(@"").Match(tableText.Value).Value + "{0}";
//模板绑定数据在Table 第2Tr中,遍历第2个Tr 匹配数据 生成多个Tr,重新凭借数据
Regex trRegex = new Regex(@"[\s\S]*?");
var trArray = trRegex.Matches(tableText.Value);
if (trArray == null || trArray.Count < 2) { sb.AppendFormat(string.Format("{0};", str)); continue; }
//无论是否匹配到Td数据 此处做拼接字符串数据
StringBuilder newStrTr = new StringBuilder();
newStrTr.Append(trArray[0].Value);
//处理第二个Tr
var tdArray = tdRegex.Matches(trArray[1].Value);
if (tdArray == null) { sb.AppendFormat(string.Format("{0};", str)); }
//根据第一个td锁定绑定的数据源
int index = 0;
var firstTd = tdContentRegex.Match(tdArray[0].Value);
string firstTdValue = firstTd.Value.Replace(">", "").Replace("<", "");
var firstSourceValue = firstTdValue.Split('_');
if (firstSourceValue != null || firstSourceValue.Length == 2)
{
var sourceName = firstSourceValue[0];
foreach (var item in itemslist)
{
//根据nameArray[0]匹配数据源
if (sourceName.Equals(item.DataSourceFlag))
{
//已匹配大数据源 此处数据源应该是明细
int rowNo = 1;
var dt = datasource[index];
if (dt == null || dt.Rows.Count < 1) break;
//遍历data 遍历第二个Tr下所有Td
foreach (DataRow dr in dt.Rows)
{
newStrTr.Append("");
for (int i = 0; i < tdArray.Count; i++)
{
var tdContent = tdContentRegex.Match(tdArray[i].Value);
string tdText = tdContent.Value.Replace(">", "").Replace("<", "");
var nameArray = tdText.Split('_');
string newValue = string.Empty;
var objectName = nameArray[1];
try
{
if (objectName == "RowNumber")
{
newValue = rowNo.ToString();
}
else if (objectName.Contains("Date"))
{
newValue = Convert.ToDateTime(dr[objectName]).ToString("yyyy-MM-dd");
}
else if (objectName.Contains("Amount") || objectName.Contains("Money") || objectName.Contains("Volumes"))
{
newValue = Convert.ToDecimal(dr[objectName]).ToString("0.####");
}
else
{
newValue = dr[objectName].ToString();
}
}
catch (Exception ex)
{
newValue = "数据匹配异常";
}
var newStrTd = tdArray[i].Value.Replace(tdText, newValue);
newStrTr.Append(newStrTd);
}
newStrTr.Append(" ");
rowNo++;
}
break;
}
index++;
}
}
newTblText = string.Format(newTblText, newStrTr.ToString());
//替换值
var newStr = str.Replace(tableText.Value, newTblText);
sb.Append($"{newStr};");
#endregion
}
else if (str.Contains("LODOP.ADD_PRINT_BARCODEA"))
{
#region 处理条码、二维码
//LODOP.ADD_PRINT_BARCODEA("data1_test2",394,98,291,60,"128A","123456789012");
var matchContent = regex.Match(str);//获取到的是"Obj.Code",12,77,100,20,"001"
if (matchContent == null)
{
sb.AppendFormat(string.Format("{0};", str));
continue;
}
var arrayData = matchContent.Value.Split(',');
var strStart = arrayData[0].Replace("\"", "");
var strReplace = arrayData.LastOrDefault().Replace("\"", "");
//注: name[0]标准值应该是 数据标识_字段名称
var nameArray = strStart.Split('_');
if (nameArray.Length != 3)
{
sb.AppendFormat(string.Format("{0};", str));
continue;
}
var i = 0;
object newValue = null;
bool IsMatch = false;//是否匹配到数据 如果没有则返回原文
foreach (var item in itemslist)
{
if (nameArray[0].Equals(item.DataSourceFlag))
{
//已匹配大数据源
var dt = datasource[i];
if (dt == null || dt.Rows.Count < 1) break;
//根据反射找到数据值
var objectName = nameArray[1];
foreach (DataRow dr in dt.Rows)
{
try
{
if (dr[objectName] != null)
{
if (objectName.Contains("Date"))
{
newValue = Convert.ToDateTime(dr[objectName]).ToString("yyyy-MM-dd");
}
else if (objectName.Contains("Amount") || objectName.Contains("Money"))
{
newValue = Convert.ToDecimal(dr[objectName]).ToString("0.####");
}
else
{
newValue = dr[objectName];
}
IsMatch = true;
}
}
catch
{
}
}
break;
}
i++;
}
if (IsMatch)
{
//替换值
var newStr = str.Replace(strReplace, newValue.ToString());
sb.AppendFormat(string.Format("{0};", newStr));
}
else
{
sb.AppendFormat(string.Format("{0};", str));
}
#endregion
}
else
{
sb.AppendFormat(string.Format("{0};", str));
}
}
}