C# .NET 6 使用 BarTender 打印资产标签并生成 PDF 预览
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Nodes;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services
.AddCors(options =>
options.AddDefaultPolicy(
builder => builder
.WithOrigins("*")
.AllowAnyHeader()
.AllowAnyMethod()
)
)
.AddQueuePolicy(options =>
{
options.MaxConcurrentRequests = 1;
options.RequestQueueLimit = 5;
}
);
WebApplication app = builder.Build();
app.UseCors();
app.UseConcurrencyLimiter();
app.MapPost("/print", ([FromBody] JsonObject requestBody, ILogger<Program> logger) =>
{
string type = (string)requestBody['type']!;
List<AssetTag> assetTagList = requestBody['assets'].Deserialize<List<AssetTag>>()!;
string rootPath = $"{app.Environment.WebRootPath}\file";
string guid = Guid.NewGuid().ToString();
logger.LogInformation($"[{guid}]开始运行资产标签打印服务,正在导入数据...");
PropertyInfo[] propertyInfos = new AssetTag().GetType().GetProperties();
using (XSSFWorkbook workbook = new())
{
ISheet sheet = workbook.CreateSheet("Sheet1");
for (int i = 0, length = assetTagList.Count + 1; i < length; i++)
{
IRow row = sheet.CreateRow(i);
for (int j = 0; j < propertyInfos.Length; j++)
{
if (i == 0)
{
row.CreateCell(j).SetCellValue(propertyInfos[j].Name);
}
else
{
row.CreateCell(j).SetCellValue((string)propertyInfos[j].GetValue(assetTagList[i - 1], null)!);
}
}
}
using FileStream fileStream = File.Open($"{rootPath}\template\data.xlsx", FileMode.Create, FileAccess.Write);
workbook.Write(fileStream);
}
logger.LogInformation($"[{guid}]数据已导入EXCEL,正在启动BarTender打印...");
BarTender.Application application = new();
BarTender.Format format = application.Formats.Open($"{rootPath}\template\asset-tag-{type}.btw");
format.Printer = "Foxit PDF Reader Printer";
format.PrintOut(false, false);
format.Close(BarTender.BtSaveOptions.btDoNotSaveChanges);
application.Quit(BarTender.BtSaveOptions.btDoNotSaveChanges);
GC.Collect();
string assetTagFilePath = $"{rootPath}\export\asset-tag-{type}.pdf";
string exportFilePath = $"{rootPath}\export\{guid}.pdf";
File.Copy(assetTagFilePath, exportFilePath);
logger.LogInformation($"[{guid}]打印成功,已生成导出文件(文件保留2分钟)");
Task.Run(async () =>
{
await Task.Delay(2 * 60 * 1000);
File.Delete(exportFilePath);
logger.LogInformation($"[{guid}]已删除导出文件");
});
return Results.Ok(guid);
});
app.MapGet("/preview/{id}", ([FromRoute] string id) =>
{
string path = $"{app.Environment.WebRootPath}\file\export\{id}.pdf";
if (!File.Exists(path))
{
return Results.NotFound("文件不存在");
}
return Results.File(path, "application/pdf");
});
app.Run("http://*:8086");
internal class AssetTag
{
public string? Company { get; set; }
public string? Id { get; set; }
public string? Name { get; set; }
public string? Model { get; set; }
public string? Attribute { get; set; }
public string? ArrivalDate { get; set; }
public string? ManagementLevel { get; set; }
}
在上述代码中,使用的是 `class` 关键字定义了一个名为 `AssetTag` 的类。在这种情况下,使用 `class` 是合适的选择。
`record` 是 C# 9 中引入的一种新的引用类型,用于表示不可变的数据结构。它具有自动实现的 `equals`、`getHashCode` 和 `ToString` 方法,以及方便的构造函数和属性初始化语法。然而,在这段代码中,并没有对 `AssetTag` 进行不可变性的要求,也没有需要使用 `record` 特性提供的自动实现方法的需求。
对于 `struct`,它是一种值类型,适用于较小的数据结构,通常用于存储和传递简单的数据值。在这段代码中,`AssetTag` 需要存储和传递多个属性值,并且可能需要进行更复杂的操作,因此使用 `class` 更合适。
综上所述,使用 `class` 关键字定义 `AssetTag` 类是最适合的选择。
原文地址: https://www.cveoy.top/t/topic/pzxt 著作权归作者所有。请勿转载和采集!