您好我正在尝试使用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);
}
答案 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.Format
或Console.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);
}
}