打印配置
默认只需后台初始化打印的表与字段及后台管理页面【打印管理】设计模板
1、初始化打印配置
在Startup.cs文件ConfigureContainer中初始化打印配置
查看配置代码
public void ConfigureContainer(ContainerBuilder builder)
{
/*************打印配置**************/
PrintContainer.Instance
/*****************[全国城市]单表打印*****************/
.Use<Sys_Region>(
//主表配置
name: "地址打印管理",
//主表可以打印的字段
printFields: x => new { x.name, x.code, x.mername, x.pinyin, x.Lat, x.Lng }
)
//主从明细表同时打印(注意Use第一个参数是主表,第二个明细表)
.Use<Demo_Order, Demo_OrderList>(
//主表配置
name: "订单打印管理",
//主表可以打印的字段
printFields: x => new { x.OrderNo, x.OrderStatus, x.OrderType, x.OrderDate, x.TotalPrice, x.TotalQty },
//明细表配置
detailName: "订单详情",
//明细表可以打印的字段
detailPrintFields: c => new { c.GoodsCode, c.GoodsName, c.Specs, c.Price, c.Qty }
)
/*****************[订单表]打印配置(主从明细表明细表(一对一))*****************/
.Use<Demo_Order,Demo_OrderList>(
//主表配置
name: "订单打印管理",
//主表可以打印的字段
printFields: x => new { x.OrderNo, x.OrderStatus, x.OrderType, x.OrderDate, x.TotalPrice, x.TotalQty },
//主表自定义打印的字段,没有就填null;需要在:PrintCustom类QueryResult字自定义返回这些字段的值
customFields: new List<CustomField>() {
new CustomField() { Name="自定义1", Field="test1" } ,
new CustomField() { Name="自定义2", Field="test2" }
},
//明细表配置
detail:new PrintDetailOptions<Demo_OrderList>() {
Name = "订单详情",
PrintFields = c => new { c.GoodsCode, c.GoodsName, c.Specs, c.Price, c.Qty },
//明细表自定义的字段,没有就填null;需要在:PrintCustom类QueryResult字自定义返回这些字段的值
CustomFields = new List<CustomField>() {
new CustomField() { Name="明细自定义1", Field="test1" } ,
new CustomField() { Name="明细自定义2", Field="test2" }
}
}
)
/*****************[产品表]打印配置(一对多打印)*****************/
.Use<Demo_Product, Demo_ProductSize, Demo_ProductColor>(
//主表配置
name: "一对多打印测试",
//主表可以打印的字段
printFields: x => new { x.ProductName, x.ProductCode, x.AuditStatus, x.Price, x.Remark, x.CreateDate },
//主表自定义打印的字段,没有就填null;需要在:PrintCustom类QueryResult字自定义返回这些字段的值
customFields:null,//配置同上
//明细表[产品尺寸]打印配置
detail1: new PrintDetailOptions<Demo_ProductSize>()
{
Name = "产品尺寸",
//明细表打印的字段
PrintFields = x => new { x.ProductId, x.Size, x.Unit, x.Remark, x.Creator, x.CreateDate },
//明细表自定义的字段,需要在:PrintCustom类QueryResult字自定义返回这些字段的值
CustomFields = null //自定义字段同上配置一样
},
//明细表[产品颜色]打印配置
detail2: new PrintDetailOptions<Demo_ProductColor>()
{
Name = "产品颜色",
//明细表打印的字段
PrintFields = x => new { x.ProductId,x.Img,x.Color, x.Qty, x.Unit, x.Remark, x.Creator, x.CreateDate },
//明细表自定义的字段需要在:PrintCustom类QueryResult字自定义返回这些字段的值
CustomFields = null //自定义字段同上配置一样
}
);
}
2.设置打印模板
打印设计菜单,点击新建配置打印名称,再点击表格操作列,设置打印模板
3.菜单配置
在菜单配置,勾上打印按钮
打印分页问题
打印文本与表格重叠问题
标签文本不要与上面表格位置靠太近了或者使用长文本配置
后台打印方法实现
自定义返回内容实现说明
1. 正常打印只需要界面配置,不用写代码,如果需要返回自定义信息,如:打印的某些字段需要从其他表返回
2. 实现下面的QueryResult即可,也可以参照下面【自定义打印内容(合计配置)】
后台代码配置
查看配置代码
/*在PrintCustom.cs中可实现自定义返回打印的数据**************/
public class PrintCustom : PrintFilter
{
public PrintCustom() { }
/// <summary>
/// 主表查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query"></param>
/// <param name="parms"></param>
/// <returns></returns>
public override IQueryable<T> Query<T>(IQueryable<T> query, PrintQuery parms) where T : class
{
//判断是哪张主表自定义过滤条件
if (typeof(T).Name == typeof(Demo_Order).Name)
{
var orderQuery = ((IQueryable<Demo_Order>)query);
//排序操作:orderQuery=orderQuery.OrderBy(x=>x.字段)
return orderQuery
//这里where可以写自定义条件
.Where(x => true) as IQueryable<T>;
}
return query;
}
/// <summary>
/// 明细表查询
/// </summary>
/// <typeparam name="Detail"></typeparam>
/// <param name="query"></param>
/// <param name="parms"></param>
/// <returns></returns>
public override IQueryable<Detail> QueryDetail<Detail>(IQueryable<Detail> query, PrintQuery parms) where Detail : class
{
//判断是哪张明细表自定义过滤条件
if (typeof(Detail).Name == typeof(Demo_OrderList).Name)
{
var orderQuery = ((IQueryable<Demo_OrderList>)query);
//排序操作:orderQuery=orderQuery.OrderBy(x=>x.字段)
return orderQuery
//这里where可以写自定义条件
.Where(x => true) as IQueryable<Detail>;
}
return query;
}
/// <summary>
/// 对返回的结果自定义处理
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Detail"></typeparam>
/// <param name="result"></param>
/// <param name="parms"></param>
/// <returns></returns>
public override List<Dictionary<string, object>> QueryResult<T>(
List<Dictionary<string, object>> result,
PrintQuery parms,
BaseDbContext dbContext)
{
if (result.Count == 0) return result;
//判断表,自定义返回数据
if (typeof(T).Name == typeof(Demo_Order).Name)
{
//判断是哪个打印模板,然后自定义返回数据
if (parms.TemplateName == "订单管理主从明细表打印")
{
//返回DemoOrder表自定义配置
SetDemoOrderValue(result, parms, dbContext);
}
}
return result;
}
/// <summary>
/// 返回DemoOrder表自定义配置
/// </summary>
/// <param name="result"></param>
/// <param name="parms"></param>
/// <param name="dbContext"></param>
private void SetDemoOrderValue(
List<Dictionary<string, object>> result,
PrintQuery parms,
BaseDbContext dbContext)
{
//给明细表设置合计
var data = dbContext.Set<Demo_OrderList>()
//根据主表id查询返回明细表合计
.Where(x => x.Order_Id == parms.Ids[0].GetGuid())
.GroupBy(x => true)
.Select(s => new
{
单价合计 = s.Sum(c => c.Price),
数量合计 = s.Sum(c => c.Qty)
}).FirstOrDefault();
//设置自定义返回的字段(模板设计页面需要定义:单价合计、数量合计两个字段)
result[0]["单价合计"] = data?.单价合计 ?? 0;
result[0]["数量合计"] = data?.数量合计 ?? 0;
//result[0]这里还可以自定义其他字段设置值与模板设计页面定义的字段一致即可
////例如:再返回一些自定义的表格数据
//var otherTable = dbContext.Set<Demo_Product>()
// .Where(x => true)//这里写条件
// .Select(s => new
// {
// 名称 = s.ProductName,//[名称]与[编号]是打印板自定义表格的里面输入的字段名
// 编号 = s.ProductCode
// }).ToList();
//result[0]["字段名"] = otherTable;
}
}
自定义打印内容
自定义表格及字段,后台返回对应名称
1.表格配置
2.字段配置
3.后台实现
在后台PrintCustom.cs方法QueryResult<T>中
返回实际数据
查看配置代码
public override List<Dictionary<string, object>> QueryResult<T>( List<Dictionary<string, object>> result, PrintQuery parms,BaseDbContext dbContext)
{
if (result.Count == 0) return result;
//判断表与打印模板,自定义返回数据
if (typeof(T).Name == typeof(Demo_Order).Name&&parms.TemplateName == "测试模板")
{
//parms.Ids是勾选的主表主键id
List<Guid?> ids = parms.Ids.Select(s => s.GetGuid()).ToList();
//自定义查询返回表格数据
var data = dbContext.Set<Demo_OrderList>().Where(x => ids.Contains(x.Order_Id))
.Select(s => new
{
s.Order_Id,//主表主键id
Name = s.GoodsName,//这里的字段名与第2步截图的字段名要一致
Qty = s.Qty//其他字段同上
}).ToList();
//循环要打印的数据
foreach (var item in result)
{
Guid? id = item["Order_Id"].GetGuid();
//获取每行打印的表格数据
var list = data.Where(x => x.Order_Id == id).ToList();
//设置自定义表格数据,第2步截图的字段名要一致
item["Table1"] = list;
}
}
return result;
}
自定义打印内容
后台返回字段,其他配置类似(如果要做配置合计,在打印模板右边的高级属性可以直接配置,这里只是举例自定义字段)
自定义打印页面内容
自定义打印模板配置
后台代码配置
/************在PrintCustom.cs中实现QueryResult方法,并根据条件判断调用自定义方法**************/
/// <summary>
/// 对返回的结果自定义处理
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Detail"></typeparam>
/// <param name="result"></param>
/// <param name="parms"></param>
/// <returns></returns>
public override List<Dictionary<string, object>> QueryResult<T, Detail>(
List<Dictionary<string, object>> result,
PrintQuery parms,
BaseDbContext dbContext)
{
if (result.Count == 0) return result;
//自定义处理,并调用下面自定义方法SetDemoOrderValue
//判断表,自定义返回数据
if (typeof(T).Name == typeof(Demo_Order).Name)
{
//判断是哪个打印模板,然后自定义返回数据
if (parms.TemplateName == "订单管理主从明细表打印")
{
//返回DemoOrder表自定义配置
SetDemoOrderValue(result, parms, dbContext);
}
}
return result;
}
/// <summary>
/// 这个方法SetDemoOrderValue是自定义的: 返回DemoOrder表自定义配置(返回合计内容)
/// </summary>
/// <param name="result"></param>
/// <param name="parms"></param>
/// <param name="dbContext"></param>
private void SetDemoOrderValue(
List<Dictionary<string, object>> result,
PrintQuery parms,
BaseDbContext dbContext)
{
//从数据库统计明细表合计
var data = dbContext.Set<Demo_OrderList>()
//根据主表id查询返回明细表合计
.Where(x => x.Order_Id == parms.Ids[0].GetGuid())
.GroupBy(x => true)
.Select(s => new
{
单价合计 = s.Sum(c => c.Price),
数量合计 = s.Sum(c => c.Qty)
}).FirstOrDefault();
//设置自定义返回的字段(模板设计页面需要定义:单价合计、数量合计两个字段)
//注意,这里【单价合计】名字与第二张图的第4步字段名必须一致
result[0]["单价合计"] = data?.单价合计 ?? 0;
result[0]["数量合计"] = data?.数量合计 ?? 0;
//result[0]这里还可以自定义其他字段设置值与模板设计页面定义的字段一致即可
////例如:再返回一些自定义的表格数据
//var otherTable = dbContext.Set<Demo_Product>()
// .Where(x => true)//这里写条件
// .Select(s => new
// {
// 名称 = s.ProductName,//[名称]与[编号]是打印板自定义表格的里面输入的字段名
// 编号 = s.ProductCode
// }).ToList();
//result[0]["字段名"] = otherTable;
}
打印回调
用户只要点击了打印按钮就会回调,监听不了打印成功还是失败
1、打印配置设置回调接口地址
填写回调的接口地址
2、接口实现
以Sys_Region表为例,在表的控制器上写更新方法,接口名与上面的配置的接口要一致
public partial class Sys_RegionController
{
private readonly ISys_RegionService _service;//访问业务代码
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ISys_RegionRepository _regionRepository;
[ActivatorUtilitiesConstructor]
public Sys_RegionController(
ISys_RegionService service,
IHttpContextAccessor httpContextAccessor,
ISys_RegionRepository regionRepository
)
: base(service)
{
_service = service;
_regionRepository = regionRepository;
_httpContextAccessor = httpContextAccessor;
}
[Route("printCallback"), HttpPost]
public IActionResult PrintCallback([FromBody] int[] ids)
{
//这里自己写脚本更新
//1、EF写法
string sql = " update Sys_Region set 更新的字段=值 where 主键字段 in @ids";
_regionRepository.DapperContext.ExcuteNonQuery(sql, new { ids });
//2、sqlsugar写法
//string sql = " update Sys_Region set 更新的字段=值 where 主键字段 in (@ids)";
//var sugarParameter = new SugarParameter("@ids", "张三");
//_regionRepository.SqlSugarClient.Ado.ExecuteCommand(sql, sugarParameter);
return Content("更新成功");
}
}