打印到PDF

时间:2015-12-27 12:40:38

标签: c# string pdf formatting itextsharp

我正在尝试用PDF打印两列信息,其中包含用户输入的一些字符串。到目前为止,这是我的代码:

string s = "";
int width = 60 - name.Count(Char.IsWhiteSpace);                                                                  
s = s + string.Format("{0,-" + width +"}", "Name: " + name);
s = s + string.Format("{0,15}","AAA: ");
p1.Add(s);
document.Add(p1);

string p = "";
int width = 60 - surname.Count(Char.IsWhiteSpace);                                                                 
p = p + string.Format("{0,-"+ width +"}", "Surname: " + surname);
p = p + string.Format("{0,15}","BBB: ");
p2.Add(p);
document.Add(p2);

string r = ""; 
int width = 60 - school.Count(Char.IsWhiteSpace);                                                       
r = r + string.Format("{0,-"+ width +"}", "School: " + school);
r = r + string.Format("{0,15}","CCC: ");
p3.Add(r);
document.Add(p3);

如果用户输入,例如“John Edward Jr.”为了名字,“Pascal Einstein W. Alfi”为姓氏,“圣约翰”为学校,那么预期的输出是这样的:

Name: John Edward Jr.________________AAA:

Surname: Pascal Einstein W. Alfi_______BBB:

School: St. John___________________CCC:

我想每个字符串名称,姓氏和学校中的空格都是问题所在。我怎么处理这个?

预期输出:

Name: John Edward Jr.__________________AAA:

Surname: Pascal Einstein W. Alfi_______BBB:

School: St. John_______________________CCC:

编辑:

int width = 60 - name.Count(Char.IsWhiteSpace);

3 个答案:

答案 0 :(得分:4)

假设我们想要以表格格式呈现此数据:

public static final String[][] DATA = {
    {"John Edward Jr.", "AAA"},
    {"Pascal Einstein W. Alfi", "BBB"},
    {"St. John", "CCC"}
};

使用iText有三种方法可以实现这一目标。

解决方案#1:使用表格

请查看SimpleTable13示例:

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream(dest));
    document.open();
    PdfPTable table = new PdfPTable(2);
    table.setWidthPercentage(50);
    table.setHorizontalAlignment(Element.ALIGN_LEFT);
    table.setWidths(new int[]{5, 1});
    table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
    table.addCell("Name: " + DATA[0][0]);
    table.addCell(DATA[0][1]);
    table.addCell("Surname: " + DATA[1][0]);
    table.addCell(DATA[1][1]);
    table.addCell("School: " + DATA[2][0]);
    table.addCell(DATA[1][1]);
    document.add(table);
    document.close();
}

我们创建一个包含2列的表,然后添加6个单元格。这将产生一个包含2列和3行的表。当我们删除边框时,正如我们告诉表格第一列的宽度应该是第二列的5倍,结果如下:

enter image description here

优点:如果其中一个单元格中有太多文本,那么内容将自动换行,表格的大小将适应内容。

解决方案#2:使用标签

请查看TableTab示例:

public void createPdf(String dest) throws FileNotFoundException, DocumentException {
    Document document = new Document();

    PdfWriter.getInstance(document, new FileOutputStream(dest));

    document.open();

    document.add(createParagraphWithTab("Name: ", DATA[0][0], DATA[0][1]));
    document.add(createParagraphWithTab("Surname: ", DATA[1][0], DATA[1][1]));
    document.add(createParagraphWithTab("School: ", DATA[2][0], DATA[2][1]));

    document.close();
}

public Paragraph createParagraphWithTab(String key, String value1, String value2) {
    Paragraph p = new Paragraph();
    p.setTabSettings(new TabSettings(200f));
    p.add(key);
    p.add(value1);
    p.add(Chunk.TABBING);
    p.add(value2);
    return p;
}

在此示例中,我们创建了一个段落,我们为其定义了200个用户单元的选项卡。现在,当我们添加Chunk.TABBING时,内容将跳转到该位置。结果如下:

enter image description here

缺点:当第一列中的文本太多时,该文本将进入第二列,并且将在接下来的200个用户单元中添加一个选项卡(可以在同一行上,可以在下一个线)。

解决方案#3:使用空格和等宽字体

这就是你正在做的事情,除了你没有使用不能提供你想要的结果的等宽字体。

请查看TableSpace示例:

public void createPdf(String dest) throws DocumentException, IOException {
    Document document = new Document();

    PdfWriter.getInstance(document, new FileOutputStream(dest));

    document.open();

    BaseFont bf = BaseFont.createFont(FONT, BaseFont.CP1250, BaseFont.EMBEDDED);
    Font font = new Font(bf, 12);

    document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Name", DATA[0][0]), DATA[0][1]));
    document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Surname", DATA[1][0]), DATA[1][1]));
    document.add(createParagraphWithSpaces(font, String.format("%s: %s", "School", DATA[2][0]), DATA[2][1]));

    document.close();
}

public Paragraph createParagraphWithSpaces(Font font, String value1, String value2) {
    Paragraph p = new Paragraph();
    p.setFont(font);
    p.add(String.format("%-35s", value1));
    p.add(value2);
    return p;
}

现在我们格式化第一个String,以便它总是测量35个字符。结果如下:

enter image description here

缺点:如果第一列中的文本需要超过35个字符,它将通过第二列运行,第二列的文本将粘贴到它。你还看到我需要使用不同的字体。我使用PTMono-Regular。通常,等宽字体中的文本比比例字体中的文本占用更多空间。有关等宽字体的更多信息,请阅读我的答案:How to set monospaced font by using iTextSharp?

答案 1 :(得分:0)

问题是您在打印到PDF时使用的间距键。 只需使用非中断空格(按Alt + <255>),或者您可以使用以下代码转换空格:

string s = " ";
if(s == " ")
{
 s = "&nbsp;"
}

使用"My name is this".Replace(" ", "&nbsp;");

更新2

由于您使用的是iText#,您可以使用API​​来插入空格,例如:

iTextSharp.text.Paragraph s = new iTextSharp.text.Paragraph(name, font);
s.SpacingAfter = 20;
s.Add("AAA: ");

如果我的回答支持你的问题,请告诉我。

答案 2 :(得分:0)

我在下面尝试了这个。它对我有用。您正在使用(60 - name.size)名称宽度,但您没有使用(name.width)AAA。如果你使用这个,那么总宽度将是=(60 - name.size)+ name.size = 60. [我认为这是你想要的。]。祝你好运。

string name = "John Edward Jr.";
        string surname = "Pascal Einstein W. Alfi";
        string school = "St. John";
        string s = "";
        int charWidth = 0;
        int width = 60 - name.Count();
        charWidth = name.Count();
        s = s + string.Format("{0,-" + width + "}" + "{1," + charWidth + "}", "Name: " + name, "AAA: ");
        Console.WriteLine(s);
        s = "";
        width = 60 - surname.Count();
        charWidth = surname.Count();
        s = s + string.Format("{0,-" + width + "}" + "{1," + charWidth + "}", "Surname: " + surname, "BBB: ");
        Console.WriteLine(s);
        s = "";
        width = 60 - school.Count();
        charWidth = school.Count();
        s = s + string.Format("{0,-" + width + "}" + "{1," + charWidth + "}", "School: " + school, "CCC: ");
        Console.WriteLine(s);