web-dev-qa-db-fra.com

Écrire un bon reçu en C # WPF pour l’impression sur une imprimante thermique POS

J'essaie d'implémenter la fonctionnalité d'impression dans l'un de mes projets mais je ne suis pas très bon dans ce genre de travail.

Je me suis déjà connecté à mon imprimante thermique et écrit/imprime les mêmes échantillons ..___ Maintenant, j'essaie de trouver un moyen de concevoir mon reçu de manière à ce qu'il ressemble à un reçu à partir de l'image jointe.

J'ai quelques idées mais je ne suis pas sûr qu'elles conviennent à ce type de travail. L'une d'elles est d'essayer de formater mon reçu au format HTML et de le rendre au format HTML, comme bitmap (image), puis de l'imprimer. il semble que j'ai une perte de qualité.

Si quelqu'un a d'autres idées sur la façon dont je peux créer un reçu ressemblant à l'image, partagez cette information avec moi. Je vous en serai très reconnaissant.

C’est ce que j’ai déjà fait pour imprimer des échantillons. Pour le formatage, j’ai utilisé graphics.DrawString mais je ne pense pas que je puisse accomplir beaucoup de choses en l’utilisant.

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

}

enter image description here

15
Nic

Auparavant, je divisais le reçu en plusieurs parties utilisant des polices ou des alignements différents, tels que En-tête, Corps, Pied de page. 

J'ai utilisé la disposition de classe suivante pour encapsuler ma définition de texte imprimé . (D'où vous obtenez la police et comment vous gérez sa durée de vie, cela dépend de vous)

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

Lorsqu'il y a de longues listes de textes utilisant la même police et le même remplissage, l'utilisation d'un constructeur de chaînes pour construire votre texte vous simplifie la vie, vous permettant ainsi d'obtenir un aperçu visuel de son apparence après inspection du code.

Si vous aviez du texte statique, vous pouvez tout assembler de la manière suivante:

var sb = new StringBuilder();
sb.AppendLine("Start of receipt");
sb.AppendLine("================");
sb.AppendLine("Item 1");
sb.AppendLine("Item 2");
sb.AppendLine("================");

Ou, si les données sont un peu dynamiques, passez un objet, vous pouvez effectuer une itération et ajouter votre texte mis en forme:

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("================");

La sortie ressemblera à:

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
================

En utilisant la classe PrintText plus tôt, nous pouvons stocker notre sortie de constructeur de chaînes bien formatée

var printText = new PrintText(sb.ToString(), new Font("Monospace Please...", 8));

Enfin, utilisez-le lorsque vous essayez de tirer la chaîne

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

Vous pouvez également jouer avec quelques modifications graphiques différentes si le texte ne s’imprime pas correctement, par exemple:

g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
20
laurencee

je suppose que vous n'imprimez pas la sortie sur une imprimante thermique, mais sur une imprimante compatible bitmap haute résolution normale? si votre problème vous oblige à générer un bitmap/pdf ou une autre description graphique que vous pouvez ensuite envoyer à l’imprimante. Comme l'exemple que vous avez fourni ne contient que du texte, votre tâche consiste simplement à le mettre en page avec les coordonnées et la taille de la police. Le problème que vous rencontrerez est toutefois de trouver les bonnes polices et d’obtenir l’espacement, le crénage, etc. parfaitement. ce serait mon point de départ. voyez si vous pouvez trouver une police qui ressemble à celle de l'image. testez-le dans Photoshop/Gimp ou similaire. Faites en sorte que votre photo de la termale imprime un calque d'arrière-plan, puis voyez si vous pouvez obtenir le même plan au premier plan. une fois que vous pouvez le copier là-bas, allez et terminez le logiciel. Choisissez les coordonnées du texte de votre maquette Photoshop. 

1
morishuz

Vous pouvez convertir le reçu en image BitMaps et utiliser la classe XpsDocuentGenerator. Ou utilisez une bibliothèque open-source telle que MigraDocs pour la convertir en PDF et l'envoyer aux imprimantes 

0
parthap