21

我一直在为餐厅/酒吧构建 POS 应用程序。
设计部分已经完成,在过去的一个月里,我一直在编写代码。
一切正常,除了现在我需要打印。我必须打印到连接到运行该软件的计算机的收据打印机,稍后我将尝试在远程打印机(如厨房的打印机)上打印。

我在这件事上搜索了帮助,却发现在这些类型的打印机中打印的标准是使用 .NET 的 POS。问题是,这现在有点过时了,或者至少几年以来它没有任何更新。有很多关于如何使用这个库的问题被问到,而且大多数答案都不太容易理解。因此,如果有人可以在收据打印机上打印一个简单的短语(“Hello World”),我将非常感激。
我正在使用在 64 位 Windows 7 上运行的 Visual Studio 2012,并且我正在 C# 中编写 WPF。

4

4 回答 4

23

我知道这是一篇旧帖子,但对于那些仍在寻找解决方案的人,我可以告诉你我做了什么。

在花了很多时间为 .Net 处理 OPOS 和 POS 之后,我最终放弃了这些,只使用了内置System.Drawing.Printing库。.Net 的 OPOS 和 POS 最终很难开始工作,并且最终无法像内置库那样工作。

我使用的是 Epson TM-T20II 收据打印机。

这是一些对我来说效果很好的代码。

public static void PrintReceiptForTransaction()
{
    PrintDocument recordDoc = new PrintDocument();

    recordDoc.DocumentName = "Customer Receipt";
    recordDoc.PrintPage += new PrintPageEventHandler(ReceiptPrinter.PrintReceiptPage); // function below
    recordDoc.PrintController = new StandardPrintController(); // hides status dialog popup
                                                                // Comment if debugging 
    PrinterSettings ps = new PrinterSettings();
    ps.PrinterName = "EPSON TM-T20II Receipt";
    recordDoc.PrinterSettings = ps;
    recordDoc.Print();
    // --------------------------------------

    // Uncomment if debugging - shows dialog instead
    //PrintPreviewDialog printPrvDlg = new PrintPreviewDialog();
    //printPrvDlg.Document = recordDoc;
    //printPrvDlg.Width = 1200;
    //printPrvDlg.Height = 800;
    //printPrvDlg.ShowDialog();
    // --------------------------------------

    recordDoc.Dispose();
}

private static void PrintReceiptPage(object sender, PrintPageEventArgs e)
{
    float x = 10;
    float y = 5;
    float width = 270.0F; // max width I found through trial and error
    float height = 0F;

    Font drawFontArial12Bold = new Font("Arial", 12, FontStyle.Bold);
    Font drawFontArial10Regular = new Font("Arial", 10, FontStyle.Regular);
    SolidBrush drawBrush = new SolidBrush(Color.Black);

    // Set format of string.
    StringFormat drawFormatCenter = new StringFormat();
    drawFormatCenter.Alignment = StringAlignment.Center;
    StringFormat drawFormatLeft = new StringFormat();
    drawFormatLeft.Alignment = StringAlignment.Near;
    StringFormat drawFormatRight = new StringFormat();
    drawFormatRight.Alignment = StringAlignment.Far;

    // Draw string to screen.
    string text = "Company Name";
    e.Graphics.DrawString(text, drawFontArial12Bold, drawBrush, new RectangleF(x, y, width, height), drawFormatCenter);
    y += e.Graphics.MeasureString(text, drawFontArial12Bold).Height;

    text = "Address";
    e.Graphics.DrawString(text, drawFontArial10Regular, drawBrush, new RectangleF(x, y, width, height), drawFormatCenter);
    y += e.Graphics.MeasureString(text, drawFontArial10Regular).Height;

    // ... and so on
}

希望它可以帮助某人跳过自定义驱动程序的所有麻烦。:)

于 2014-11-27T07:22:38.490 回答
13

.NET 的 POS 可能是要走的路。

大多数收据打印机制造商都会提供 OPOS 服务对象。

正如这篇 MSDN 文章所述,.NET 的 POS与OPOS v1.8 服务对象兼容。

OPOS / UPOS(.NET 的 POS 所基于的)恕我直言,这是一个设计不佳的 API(由设备制造商而不是应用程序开发人员设计),但它是你今天拥有的最好的。

我没有任何具体的示例,但基本与 OPOS 相同——您需要打开、声明、启用设备,然后您可以调用其方法(例如打印)。您可以尝试查看 OPOS 示例,例如这个 PosPrinter1 示例,它可能与 .NET 的 POS 非常相似。

此博客提供了一些有关为 .NET 设置 POS 的信息,这些信息可能会有所帮助。

更新

这是用于 OPOS 打印机的 VB Hello World。您首先需要创建一台打印机并将其添加到注册表中,并使用所需的逻辑设备名称 = LDN。我相信 Epson ADK 包含一个在注册表中添加打印机的实用程序。此实用程序还可以对打印机执行健康检查,以检查它是否安装正确。完成此操作后,应该很容易将下面的代码适应 POS for .NET

OPOSPOSPrinter.Open "MyPrinter"    ' LDN of your printer   
OPOSPOSPrinter.Claim 500           ' Timeout   
OPOSPOSPrinter.DeviceEnabled = True  

'- Print   
OPOSPOSPrinter.PrintNormal 2, "Hello world"  

'- Close the printer   
If OPOSPOSPrinter.Claimed then   
   OPOSPOSPrinter.Release   
End If  
OPOSPOSPrinter.Close  
于 2012-11-15T08:32:20.087 回答
5

.NET 打印

在.NET 下打印并不太难。看看这里msdn

打印到 POS/收据打印机将与打印到任何其他打印机相同,假设它是 Windows 打印机、网络或其他打印机。如果您使用的是串行打印机,事情可能会稍微困难一些,因为您可能需要使用制造商特定的 API,幸运的是,尽管如今大多数优秀的 POS 打印机都得到操作系统的完全支持。

首先,您需要在System.Printing项目中添加对 dll 的引用。

那么打印就这么简单

private void PrintText(string text)
{
    var printDlg = new PrintDialog();
    var doc = new FlowDocument(new Paragraph(new Run(text)));
    doc.PagePadding = new Thickness(10);

    printDlg.PrintDocument((doc as IDocumentPaginatorSource).DocumentPaginator, "Print Caption");
}

要使用..

PrintText("Hello World");

您还可以利用PrintDialog.PrintVisual并使用 xaml 模板定义您的文档。

可以使用 PrintDialog 属性设置打印设置。

获取要打印到的打印机

private PrintQueue FindPrinter(string printerName)
{
    var printers = new PrintServer().GetPrintQueues();
    foreach (var printer in printers)
    {
        if (printer.FullName == printerName)
        {
            return printer;
        }
    }
    return LocalPrintServer.GetDefaultPrintQueue();
}

尽管在打印到收据打印机时需要记住一些事项,但您需要考虑格式。更具体地说,您需要考虑页面的宽度以及每行可以容纳多少个字符;这对我来说是很多试验和错误,尤其是在不同字体大小的情况下。

在大多数情况下,您真的不需要担心分页,打印机会在完成您的文档后自动裁切纸张。

于 2012-11-15T04:57:14.707 回答
1

如果您想以打印机的全速打印,您可能需要使用特定于打印机的转义码,并生成“原始”输出。

看看 Michael Buen 对这个 SO question的回答,尤其是 UPDATE 位。

于 2012-11-15T06:08:34.960 回答