核心想法:基于模板,数据与样式分离,不希望把数据和样式混在一起拼接。
模板,使用WPF的普通Page页即可,样式布局直接使用现有的。
数据,通过DataContext绑定到页面上。
原理很简单,下面贴一下代码或截图。
模板页(一个很普通的WPF页面):

简单写了一个打印类及相应方法。
/// <summary>
/// 基于模板的打印
/// </summary>
/// <typeparam name="T">模板页类型</typeparam>
public class TemplatePrint<T>
where T : Page , new()
{
/// <summary>
/// 打印
/// </summary>
/// <param name="data">数据</param>
/// <param name="pageSize">分页时需要知道每页显示多少条记录</param>
/// <returns></returns>
public string Print<TItem>(PrintBaseData<TItem> data, int pageSize = 20) where TItem : class
{
try
{
if (data == null || data.Items == null || data.Items.Count() == 0)
{
return "无效数据";
}
if (pageSize <= 0)
{
pageSize = 20;
}
PrintDialog printDialog = new PrintDialog();
//计算总页数
int pageCount = (int)Math.Ceiling((double)data.Items.Count() / pageSize);
var allData = data.Items.ToList();
for (int i = 0; i < pageCount; i++)
{
data.Items = allData.Skip(i * pageSize).Take(pageSize).ToList();
var element = new T() { DataContext = data };
printDialog.PrintVisual(element, $"信息打印");
System.Threading.Thread.Sleep(200);
}
return "";
}
catch (Exception err)
{
return err.Message;
}
}
}
打印类是个泛型类,类型即是模板类型,这里打印类及方法的设计力求做到抽象通用。
下面提供了打印方法需要的打印数据的基类。
/// <summary>
/// 打印数据
/// </summary>
/// <typeparam name="TItem">列表项类型</typeparam>
public class PrintBaseData<TItem> where TItem : class
{
public string Title { get; set; }
public IEnumerable<TItem> Items { get; set; }
}
下面是打印功能调用的代码。
var testData = new List<QueryInfo>();
var aarea = new[] { "A", "B", "C", "D", "F" };
for (int i = 0; i < 100; i++)
{
testData.Add(new QueryInfo()
{
AreaNo = $"{aarea[i % 4]}区",
ContainerNo = $"{10 + i + ""}",
PositionName = $"{101 + i + ""}",
DrugName = $"{"药品名" + i}",
DrugSpec = $"{i + 'g'}",
StorageStatus = $"{i + 1}"
});
}
var printData = new PrintBaseData<QueryInfo>()
{
Title = "",
Items = testData
};
new TemplatePrint<QueryPrintTemplate>().Print(printData, 50);
就是这样,代码很简单,思想也简单,使用也简单。
之前研究学习了DocumentPaginator,折腾了半天,用不好,放弃了。[裂开]
浙公网安备 33010602011771号