私は自分のプロジェクトの1つに印刷機能を実装しようとしていますが、この種の作業はあまり得意ではありません。
すでにサーマルプリンターに接続し、同じサンプルを書き込み/印刷しています。今、添付された画像から領収書のように見えるように領収書を設計する方法を見つけようとしています。
私はいくつかのアイデアを持っていますが、それらがこの種の作業に適しているかどうかはわかりませんが、そのうちの1つはレシートをhtmlでフォーマットし、htmlをビットマップ(イメージ)のようにレンダリングしてから印刷することです、私はすでにこれを試しましたが、品質が低下しているようです。
画像から領収書を作成する方法について他のアイデアがある場合は、この情報を私と共有してください。とても感謝しています。
これは、いくつかのサンプルを印刷するためにすでに行ったことで、書式設定にはgraphics.DrawString
しかし、私はそれを使いすぎて達成できるとは思わない。
public void Print()
{
var doc = new PrintDocument();
doc.PrintPage += new PrintPageEventHandler(ProvideContent);
doc.Print();
}
public void ProvideContent(object sender, PrintPageEventArgs e)
{
Graphics graphics = e.Graphics;
Font font = new Font("Courier New", 10);
float fontHeight = font.GetHeight();
int startX = 0;
int startY = 0;
int Offset = 20;
e.PageSettings.PaperSize.Width = 50;
graphics.DrawString("Welcome to MSST", new Font("Courier New", 8),
new SolidBrush(Color.Black), startX, startY + Offset);
Offset = Offset + 20;
graphics.DrawString("Ticket No:" + "4525554654545",
new Font("Courier New", 14),
new SolidBrush(Color.Black), startX, startY + Offset);
Offset = Offset + 20;
graphics.DrawString("Ticket Date :" + "21/12/215",
new Font("Courier New", 14),
new SolidBrush(Color.Black), startX, startY + Offset);
Offset = Offset + 20;
String underLine = "------------------------------------------";
graphics.DrawString(underLine, new Font("Courier New", 14),
new SolidBrush(Color.Black), startX, startY + Offset);
Offset = Offset + 20;
String Grosstotal = "Total Amount to Pay = " + "2566";
Offset = Offset + 20;
underLine = "------------------------------------------";
graphics.DrawString(underLine, new Font("Courier New", 14),
new SolidBrush(Color.Black), startX, startY + Offset);
Offset = Offset + 20;
graphics.DrawString(Grosstotal, new Font("Courier New", 14),
new SolidBrush(Color.Black), startX, startY + Offset);
}
過去にこれを行うとき、レシートをヘッダー、ボディ、フッターなどの異なるフォントまたは配置を使用する別々の部分に分割しました。
次のクラスレイアウトを使用して、印刷されたテキスト定義をカプセル化しました。 (フォントをどこから取得するか、そしてその寿命をどのように管理するかはあなた次第です)
public class PrintText
{
public PrintText(string text, Font font) : this(text, font, new StringFormat()) {}
public PrintText(string text, Font font, StringFormat stringFormat)
{
Text = text;
Font = font;
StringFormat = stringFormat;
}
public string Text { get; set; }
public Font Font { get; set; }
/// <summary> Default is horizontal string formatting </summary>
public StringFormat StringFormat { get; set; }
}
同じフォントとパディングを使用するテキストのリストが長い場合、文字列ビルダーを使用してテキストを作成すると、コードを調べるだけでどのように見えるかを視覚的に確認できます。
静的テキストがある場合は、次のようにすべてを合わせることができます。
var sb = new StringBuilder();
sb.AppendLine("Start of receipt");
sb.AppendLine("================");
sb.AppendLine("Item 1");
sb.AppendLine("Item 2");
sb.AppendLine("================");
または、データがオブジェクトのビットダイナミックパスである場合は、書式設定されたテキストを反復して追加できます。
private class ReceiptItem
{
public string Name { get; set; }
public decimal Cost { get; set; }
public int Amount { get; set; }
public int Discount { get; set; }
public decimal Total { get { return Cost * Amount; } }
}
const int FIRST_COL_PAD = 20;
const int SECOND_COL_PAD = 7;
const int THIRD_COL_PAD = 20;
var sb = new StringBuilder();
sb.AppendLine("Start of receipt");
sb.AppendLine("================");
foreach (var item in receiptItems)
{
sb.Append(item.Name.PadRight(FIRST_COL_PAD));
var breakDown = item.Amount > 0 ? item.Amount + "x" + item.Cost : string.Empty;
sb.Append(breakDown.PadRight(SECOND_COL_PAD));
sb.AppendLine(string.Format("{0:0.00} A", item.Total).PadLeft(THIRD_COL_PAD));
if (item.Discount > 0)
{
sb.Append(string.Format("DISCOUNT {0:D2}%", item.Discount).PadRight(FIRST_COL_PAD + SECOND_COL_PAD));
sb.Append(string.Format("{0:0.00} A", -(item.Total / 100 * item.Discount)).PadLeft(THIRD_COL_PAD));
sb.AppendLine();
}
}
sb.AppendLine("================");
出力は次のようになります。
Start of receipt
================
Joes Food 1x10 10.00 A
DISCOUNT 10% -1.00 A
Fun Facts 1x20 20.00 A
DISCOUNT 15% -3.00 A
Bag of Sand 7x40 280.00 A
================
前にPrintTextクラスを使用すると、適切にフォーマットされた文字列ビルダー出力を保存できます
var printText = new PrintText(sb.ToString(), new Font("Monospace Please...", 8));
次に、文字列を描画するときに最後にそれを使用します
var layoutArea = new SizeF(AvailableWidth, 0);
SizeF stringSize = g.MeasureString(printText.Text, printText.Font, layoutArea, printText.StringFormat);
RectangleF rectf = new RectangleF(new PointF(), new SizeF(AvailableWidth, stringSize.Height));
g.DrawString(printText.Text, printText.Font, Brushes.Black, rectf, printText.StringFormat);
また、次のようなテキストが正しく印刷されない場合は、いくつかの異なるグラフィック調整を試してみることもできます。
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
サーマルプリンターではなく、通常の高解像度ビットマップ対応プリンターで出力を印刷すると仮定していますか?もしそうなら、あなたの問題は基本的にビットマップ/ pdfまたはプリンタに送信できる他のグラフィックス記述を生成する必要があります。指定したサンプル画像にはテキストのみが含まれているため、タスクは単にこのテキストを座標とフォントサイズでレイアウトすることです。ただし、直面する問題は、適切なフォントを調達し、スペーシングとカーニングなどを完全に正しくすることです。これが私の出発点です。画像にあるようなフォントが見つかるかどうかを確認してください。 photoshop/gimpなどでテストします。ターマルプリントの写真を背景レイヤーにして、前景を同じにできるかどうかを確認します。そこにコピーできたら、ソフトウェアを実行して終了します。 Photoshopのモックアップからテキスト座標を選択します。
レシートをBitMapsイメージに変換し、XpsDocuentGeneratorクラスを使用できます。または、MigraDocsなどのオープンソースライブラリを使用して、PDFに変換し、プリンタに送信します