C#用空格/缩进打印

时间:2016-03-23 09:32:10

标签: c# printing

您好我正在尝试使用C#应用程序中的收据打印机打印帐单/收据。

预期输出如下:

ITEM NAME                 QTY     PRICE
Banana Large Yellow        1       2.00
Brie Cheese 6 pack round   3      30.00
Indian Mango Box          10     246.00

名称,数量和价格需要以直线对齐,而不管项目名称,数量或价格中的字符数。

我一直在使用String.Format函数,但输出通常不对齐,并根据项目名称长度等间隔得到。

ITEM NAME                 QTY     PRICE
Banana Large Yellow        1       2.00
Brie Cheese 6 pack round     3      30.00
Indian Mango Box        10    246.00

如何解决这个问题?

我使用的代码是

test_string = "-------------------------------\r\n";
        test_string += "First Name | Last Name  |   Age\r\n";
        test_string += String.Format("{0,-10} | {1,-10} | {2,5}", "Bill", "Gates", 51) + "\r\n";
        test_string += String.Format("{0,-10} | {1,-10} | {2,5}", "Edna", "Parker", 114) + "\r\n";
        test_string += String.Format("{0,-10} | {1,-10} | {2,5}", "Johnny", "Depp", 44) + "\r\n";

我正在使用以下打印代码

StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;      // Horizontal Alignment 

        StringFormat right = new StringFormat();
        right.Alignment = StringAlignment.Far; 

        // Measure string.
        SizeF stringSize = new SizeF();
        pd.PrintPage += delegate(object sender, PrintPageEventArgs e)
            {
                string measureString = data;
                Font stringFont = new Font("Arial", 16);


                stringSize = e.Graphics.MeasureString(measureString, stringFont);

                RectangleF rect = new RectangleF(0, height_value, pd.DefaultPageSettings.PrintableArea.Width, pd.DefaultPageSettings.PrintableArea.Height);                   
                if (weight == "bold")
                {
                    if (alignment == "center")
                    {
                        e.Graphics.DrawString(data, new Font(font, 11, System.Drawing.FontStyle.Bold), new SolidBrush(System.Drawing.Color.Black), rect, format);
                    }
                    else
                    {
                        e.Graphics.DrawString(data, new Font(font, 11, System.Drawing.FontStyle.Bold), new SolidBrush(System.Drawing.Color.Black), rect);
                    }
                }
                else
                {
                    if (alignment == "center")
                    {
                        e.Graphics.DrawString(data, new Font(font, 11), new SolidBrush(System.Drawing.Color.Black), rect, format);
                    }
                    else if (alignment == "right")
                    {
                        e.Graphics.DrawString(data, new Font(font, 11), new SolidBrush(System.Drawing.Color.Black), rect, right);                           
                    }
                    else
                    {
                        e.Graphics.DrawString(data, new Font(font, 11), new SolidBrush(System.Drawing.Color.Black), rect);
                    }

                }
                height_value = Convert.ToInt32(stringSize.Height) + height_value;
            };

在上面的打印代码中,我将数据作为

传递
public string Test()
    {
        string[] names = { "Banana Large Yellow", "Brie Cheese", "Indian Mango Box" };
        int[] quantities = { 1, 3, 10 };
        decimal[] prices = { 2.00m, 30.00m, 246.00m };

        string format = "{0,-25} {1,-10} {2,5}" + Environment.NewLine;
        var stringBuilder = new StringBuilder().AppendFormat(format, "Item Name", "QTY", "Price");
        for (int i = 0; i < names.Length; i++)
        {
            stringBuilder.AppendFormat(format, names[i], quantities[i], prices[i]);
        }

     PrintFormat(stringBuilder.ToString(), "Arial", "normal", "left", 20);
    }

3 个答案:

答案 0 :(得分:2)

仔细查看Alignment component,您需要增加第一个位置值,因为您的字符串超过10个字符,请尝试使用-25。

using System;
using System.Text;

public class Example
{
   public static void Main()
   {

      string[] names = { "Banana Large Yellow", "Brie Cheese", "Indian Mango Box"};
      int[] quantities = { 1,3,10}; 
      decimal[] prices = { 2.00m, 30.00m, 246.00m};

      string format = "{0,-25} {1,-10} {2,10}" + Environment.NewLine;
      var stringBuilder = new StringBuilder().AppendFormat(format, "Item Name", "QTY", "Price");
      for (int i = 0; i < names.Length; i++)
      {
          stringBuilder.AppendFormat(format, names[i], quantities[i], prices[i]);
      }

      Console.WriteLine(stringBuilder.ToString());

   }
}

Item Name                 QTY             Price
Banana Large Yellow       1                2.00
Brie Cheese               3               30.00
Indian Mango Box          10             246.00

如果要在集合上循环,也不要使用字符串连接,请使用StringBuilder

我建议直接使用Environment.NewLine

答案 1 :(得分:2)

为了以类似表格的结构打印数据,您可以使用string.Format使用带宽度和对齐的格式项。

让我们来看看它是如何工作的:

// in comments underscores mean spaces
Console.WriteLine("Res:{0,6}.", 12345); //   Res:_12345.
Console.WriteLine("Res:{0,-6}.", 12345); //  Res:12345_.

但是如果得到的字符串长度超过指定的宽度呢?然后打印结果就像没有对齐和宽度一样。

Console.WriteLine("Res:{0,-6}", 123456789); //  Res:123456789.
Console.WriteLine("Res:{0,6}.", 123456789); //  Res:123456789.

因此,为了解决您的问题,首先要定义每个列中结果字符串的最大长度,并将此值用作宽度。

  

我已经使用了你建议的代码,但我没有在打印输出中得到正确对齐的小时值。我连接字符串而不是Consol.WriteLine并且在for循环外面我将它传递给打印机

您最好使用StringBuilder.AppendFormat。它适用于格式项,就像String.FormatConsole.WriteLine

答案 2 :(得分:1)

使用String.PadRight(int)。请参阅下面的代码,我使用List来存储元素,但对于数组它应该是相同的。

注意padValue1,2 and 3,通过匹配最长字的长度动态获取每列的填充值。之后我添加了2个额外的空格。

然后在打印字符串之前,添加.PadRight(padValue)

static void Main(string[] args)
{
    string itemNameTitle = "ITEM NAME";
    string qtyTitle = "QTY";
    string priceTitle = "PRICE";

    List<string> itemName = new List<string> { "Banana Large Yellow", "Brie Cheese 6 pack round", "Indian Mango Box"};
    List<string> qty = new List<string> { "1", "3", "10" };
    List<string> price = new List<string> { "2.00", "30.00", "246.00" };

    //Insert titles into first positions of Lists
    itemName.Insert(0, itemNameTitle);
    qty.Insert(0, qtyTitle);
    price.Insert(0, priceTitle);

    //Dynamically get number of spaces according to longest word length + 2
    int padValue1 = itemName.OrderByDescending(s => s.Length).First().Length + 2;
    int padValue2 = qty.OrderByDescending(s => s.Length).First().Length + 2;
    int padValue3 = price.OrderByDescending(s => s.Length).First().Length + 2;

    for (int i = 0; i < itemName.Count; i++)
    {
        Console.Write(itemName[i].PadRight(padValue1));
        Console.Write(qty[i].PadRight(padValue2));
        Console.Write(price[i]);
        Console.Write(Environment.NewLine);
    }
}