Home » Tech » PrintDocument를 사용하여 감열 식 프린터에서 텍스트 파일을 인쇄하는 방법은 무엇입니까?

PrintDocument를 사용하여 감열 식 프린터에서 텍스트 파일을 인쇄하는 방법은 무엇입니까?

https://rueisnom.com/ko/q/25daa80

Winforms와 함께 C #을 사용하여 응용 프로그램을 만들고 있는데 열 프린터에서 판매 영수증을 인쇄해야합니다. 이렇게하려면 텍스트 파일을 만들고 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);
}

이 영수증 모델을 만들려고합니다.

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 런타임 텍스트 템플릿을 사용 합니다. 그런 다음 html 템플릿으로 데이터를 전달하고 보고서를 간단하게 렌더링 할 수 있습니다. 그런 다음 출력 문자열을 WebBrowser 의 DocumentText 속성에 할당하고 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 호출 할 수 있습니다.