gpt4 book ai didi

c# - 如何使用 PrintDocument 在热敏打印机上打印文本文件?

转载 作者:行者123 更新时间:2023-11-30 13:30:09 30 4
gpt4 key购买 nike

我正在使用 C# 和 Winforms 创建一个应用程序,现在我需要在热敏打印机上打印销售收据。为此,我正在创建一个文本文件并读取它以使用 PrintDocument 进行打印,但我无法执行此操作,因为我不知道如何配置纸张大小、在纸张上对齐文本中心以及其他配置。当我打印时,文本文件被打印出来了,但是很乱,打印结束后纸张就不会停止。

我该怎么做?

尝试。

private PrintDocument printDocument = new PrintDocument();
private static String RECEIPT = Environment.CurrentDirectory + @"\comprovantes\comprovante.txt";
private String stringToPrint = "";

private void button1_Click(object sender, EventArgs e)
{
generateReceipt();
printReceipt();
}

private void generateReceipt()
{
FileStream fs = new FileStream(COMPROVANTE, FileMode.Create);
StreamWriter writer = new StreamWriter(fs);
writer.WriteLine("==========================================");
writer.WriteLine(" NOME DA EMPRESA AQUI ");
writer.WriteLine("==========================================");
writer.Close();
fs.Close();
}

private void printReceipt()
{
FileStream fs = new FileStream(COMPROVANTE, FileMode.Open);
StreamReader sr = new StreamReader(fs);
stringToPrint = sr.ReadToEnd();
printDocument.PrinterSettings.PrinterName = DefaultPrinter.GetDefaultPrinterName();
printDocument.PrintPage += new PrintPageEventHandler(printPage);
printDocument.Print();
sr.Close();
fs.Close();
}

private void printPage(object sender, PrintPageEventArgs e)
{
int charactersOnPage = 0;
int linesPerPage = 0;
Graphics graphics = e.Graphics;

// Sets the value of charactersOnPage to the number of characters
// of stringToPrint that will fit within the bounds of the page.
graphics.MeasureString(stringToPrint, this.Font,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);

// Draws the string within the bounds of the page
graphics.DrawString(stringToPrint, this.Font, Brushes.Black,
e.MarginBounds, StringFormat.GenericTypographic);

// Remove the portion of the string that has been printed.
stringToPrint = stringToPrint.Substring(charactersOnPage);

// Check to see if more pages are to be printed.
e.HasMorePages = (stringToPrint.Length > 0);
}

我正在尝试创建这种收据模型。

enter image description here

使用RDLC,但是开始打印很慢。我关注这个 example

//works but slow
private void Run() {
LocalReport report = new LocalReport();
report.ReportPath = @"..\..\reports\ReciboDeVenda.rdlc";
Export(report);
Print();
}

private void Export(LocalReport report) {
string deviceInfo =
@"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>8.5in</PageWidth>
<PageHeight>11in</PageHeight>
<MarginTop>0.25in</MarginTop>
<MarginLeft>0.25in</MarginLeft>
<MarginRight>0.25in</MarginRight>
<MarginBottom>0.25in</MarginBottom>
</DeviceInfo>";
Warning[] warnings;
m_streams = new List<Stream>();
report.Render("Image", deviceInfo, CreateStream,
out warnings);
foreach (Stream stream in m_streams)
stream.Position = 0;
}

private Stream CreateStream(string name, string fileNameExtension,
Encoding encoding, string mimeType, bool willSeek) {
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
}

private void Print() {
if (m_streams == null || m_streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
printDoc.PrinterSettings.PrinterName = DefaultPrinter.GetDefaultPrinterName();
if (!printDoc.PrinterSettings.IsValid) {
throw new Exception("Error: cannot find the default printer.");
}else {
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = 0;
printDoc.Print();
}
}

private void PrintPage(object sender, PrintPageEventArgs ev) {
Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);

// Adjust rectangular area with printer margins.
Rectangle adjustedRect = new Rectangle(
ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
ev.PageBounds.Width,
ev.PageBounds.Height);

// Draw a white background for the report
ev.Graphics.FillRectangle(Brushes.White, adjustedRect);

// Draw the report content
ev.Graphics.DrawImage(pageImage, adjustedRect);

// Prepare for the next page. Make sure we haven't hit the end.
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}

最佳答案

如果我想自己创建报告,而不是尝试创建文本文件,我将使用 HTML 进行呈现。另外为了使渲染逻辑和混合 html 标签和数据更简单,我会使用 T4 Run-time Text Templates .然后我可以将数据传递给 html 模板并简单地呈现报告。然后将输出字符串分配给 WebBrowserDocumentText 属性就足够了并称其为Print方法。

下载

您可以从 r-aghaei/HtmlUsingRuntimeT4 克隆或下载工作示例.

为什么是 HTML?

因为格式简单灵活。您可以使用 html 标签和 css 样式的所有功能来格式化文本。它确实比使用 DrawString 好。

为什么要使用运行时文本模板?

因为它使混合数据和 html 变得非常容易,并且您可以使用 C# 语言执行一些任务,例如计算总和、迭代模型记录等。它使用 T4 模板引擎,让您可以在运行时使用模板并将数据提供给模板。

示例

1- 向项目添加模型:

using System;
using System.Collections.Generic;

namespace Sample
{
public class ReportModel
{
public string CustomerName { get; set; }
public DateTime Date { get; set; }
public List<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public string Name { get; set; }
public int Price { get; set; }
public int Count { get; set; }
}
}

2- 将运行时文本模板(也称为预处理文本模板)添加到项目并将其命名为 ReportTemplate.tt。打开它并添加这样的代码:

<#@ template language="C#"#>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ parameter name="Model" type="Sample.ReportModel"#>
<html>
<head>
<title></title>
<style type="text/css">
body { font-family: Calibri;width:400px;}
table { text-align:center; }
.container {width:400px; height:100%;}
</style>
</head>
<body>
<div class="container">
<h1 style="text-align:center;">Order</h1>
<hr/>
<table style="width:100%">
<tr>
<td>Customer: <#=Model.CustomerName#></td>
<td>Order Date: <#=Model.Date#></td>
</tr>
</table>
<hr/>
<table style="width:100%">
<tr><th>Index</th><th>Name</th><th>Price</th><th>Count</th><th>Sum</th></tr>
<#
int index =1;
foreach(var item in Model.OrderItems)
{
#>
<tr>
<td><#=index#></td>
<td><#=item.Name#></td>
<td><#=item.Price#></td>
<td><#=item.Count#></td>
<td><#=item.Count * item.Price#></td>
</tr>
<#
index++;
}
var total= Model.OrderItems.Sum(x=>x.Count * x.Price);
#>
<tr><td></td><td></td><td></td><th>Total:</th><th><#=total#></th></tr>
</table>
<div>
</body>
</html>

3- 将 WebBrowser 控件放在窗体上,并在要生成报告的位置编写此类代码:

var rpt = new ReportTemplate();
rpt.Session = new Dictionary<string, object>();
rpt.Session["Model"] = new Sample.ReportModel
{
CustomerName = "Reza",
Date = DateTime.Now,
OrderItems = new List<Sample.OrderItem>()
{
new Sample.OrderItem(){Name="Product 1", Price =100, Count=2 },
new Sample.OrderItem(){Name="Product 2", Price =200, Count=3 },
new Sample.OrderItem(){Name="Product 3", Price =50, Count=1 },
}
};
rpt.Initialize();
this.webBrowser1.DocumentText= rpt.TransformText();

4- 如果你想打印报告,你可以调用:

this.webBrowser1.Print();

您应该在文档完成后调用Print。因此,如果您想直接打印而不向用户显示输出,您可以处理 DocumentCompleted 事件并在那里调用 Print

结果如下:

enter image description here

关于c# - 如何使用 PrintDocument 在热敏打印机上打印文本文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39692928/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com