如何使用PrintDocument在热敏打印机上打印文本文件? [英] How to print a text file on thermal printer using PrintDocument?

查看:151
本文介绍了如何使用PrintDocument在热敏打印机上打印文本文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#和Winforms创建一个应用程序,现在我需要在热敏打印机上打印销售收据.为此,我正在创建一个文本文件,并使用PrintDocument读取该文件以进行打印,但是我无法执行此操作,因为我不知道如何配置纸张尺寸,对齐纸张上的文本中心以及其他配置.当我执行打印时,文本文件已打印,但是全部混乱,并且在结束打印后,纸张并没有停止.

I'm creating an application using C# with Winforms and now I need to print the receipt of sale on a thermal printer. To do this I'm creating a text file and reading it to print using the PrintDocument but I cannot do this because I don't know how to configure paper size, align text center on the paper, and others configurations. When I do print the text file is printed, but all messy, and after the end print the paper isn't stopping.

我该怎么做?

尝试.

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);
}

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

使用RDLC,但是开始打印非常慢.我正在按照示例

//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);
}

推荐答案

如果将纯字符串发送到printPage(object sender, PrintEventArgs e)方法,它将仅使用看起来像"messy"(您命名的字体)的所有相同字体打印纯文本.它) 如果要用不同的字体(粗体,常规)将其打印得井井有条,则必须手动完成所有操作:

If you send a plain string to your printPage(object sender, PrintEventArgs e) method, it will just print plain text in all the same font which looks 'messy' (as you named it) If you want it to be printed well formatted with different fonts (bold, regular), you have to do it all manually:

List<string> itemList = new List<string>()
{
    "201", //fill from somewhere in your code
    "202"
};

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

    Font regular = new Font( FontFamily.GenericSansSerif, 10.0f, FontStyle.Regular );
    Font bold = new Font( FontFamily.GenericSansSerif, 10.0f, FontStyle.Bold );

    //print header
    graphics.DrawString( "FERREIRA MATERIALS PARA CONSTRUCAO LTDA", bold, Brushes.Black, 20, 10 );
    graphics.DrawString( "EST ENGENHEIRO MARCILAC, 116, SAO PAOLO - SP", regular, Brushes.Black, 30, 30 );
    graphics.DrawString( "Telefone: (11)5921-3826", regular, Brushes.Black, 110, 50 );
    graphics.DrawLine( Pens.Black, 80, 70, 320, 70 );
    graphics.DrawString( "CUPOM NAO FISCAL", bold, Brushes.Black, 110, 80 );
    graphics.DrawLine( Pens.Black, 80, 100, 320, 100 );

    //print items
    graphics.DrawString( "COD | DESCRICAO                      | QTY | X | Vir Unit | Vir Total |", bold, Brushes.Black, 10, 120 );
    graphics.DrawLine( Pens.Black, 10, 140, 430, 140 );

    for( int i = 0; i < itemList.Count; i++ )
    {
        graphics.DrawString( itemList[i].ToString(), regular, Brushes.Black, 20, 150 + i * 20 );
    }

    //print footer
    //...

    regular.Dispose();
    bold.Dispose();

    // Check to see if more pages are to be printed.
    e.HasMorePages = ( itemList.Count > 20 );
}

在我的示例中可能的改进:

Possible improvements on my example:

  • 使用graphics.MeasureString()更好地使标头字符串居中.
  • 项目列表最好是由普通字符串插入的业务类的列表
  • Centering the header strings could better be done using graphics.MeasureString().
  • List of items should better be a list of a business class insted of a plain string

由于所有工作量很大,因此您应该真正考虑使用RDLC或某些第三方软件来设计文档.

Because this all is a lot of work, you should really consider using RDLC or some third party software to design your documents.

这篇关于如何使用PrintDocument在热敏打印机上打印文本文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆