itextSharp ColumnText仅显示每个foreach循环短语

时间:2015-11-11 15:07:43

标签: c# asp.net-mvc itextsharp

我的控制器中有以下代码,使用iTextSharp显示如果列表太长而无法分割两列的危险列表。

当我运行它时,我只会在文档中显示所有其他危险。

int hazardids有28个但只有14个被显示并且检查了结果它只显示ID为偶数的危险?

ColumnText ct = new ColumnText(cb);
ct.Alignment = Element.ALIGN_JUSTIFIED;

Paragraph hazardTitle = new Paragraph("Hazards", bold);
hazardTitle.Alignment = Element.ALIGN_CENTER;
doc.Add(hazardTitle);
//Get vertical position of hazardTitle
var pos = pdfWriter.GetVerticalPosition(false);
int[] hazardIds = db.RiskAssessmentHazards
                    .Where(x => x.RiskAssessmentId == raId)
                    .OrderBy(x => x.HazardId)
                    .Select(x => x.HazardId)                                   
                    .ToArray();
foreach (int HazardIds in hazardIds)
{
    ct.AddText(new Phrase("- " + db.Hazards.FirstOrDefault(x => x.HazardId == HazardIds).Name + "\n"));
}

float gutter = 15f;

float colwidth = (doc.Right - doc.Left - gutter) / 2;               

float[] left = { doc.Left , pos,
  doc.Left , doc.Bottom };

float[] right = { doc.Left + colwidth, doc.Top - 80f, 
    doc.Left + colwidth, doc.Bottom };

float[] left2 = { doc.Right - colwidth, pos,
    doc.Right - colwidth, doc.Bottom };

float[] right2 = {doc.Right, doc.Top - 80f,
    doc.Right, doc.Bottom };

int status = 0;
int i = 0;
//Checks the value of status to determine if there is more text
//If there is, status is 2, which is the value of NO_MORE_COLUMN
while (ColumnText.HasMoreText(status))
{
    if (i == 0)
    {
        //Writing the first column
        ct.SetColumns(left, right);
        i++;
    }
    else
    {
        //write the second column
        ct.SetColumns(left2, right2);
    }

    //Needs to be here to prevent app from hanging
    ct.YLine = pos;
    //Commit the content of the ColumnText to the document
    //ColumnText.Go() returns NO_MORE_TEXT (1) and/or NO_MORE_COLUMN (2)
    //In other words, it fills the column until it has either run out of column, or text, or both
    status = ct.Go();
}

1 个答案:

答案 0 :(得分:3)

Tried your sample code, simulating your database call with an array of hard-coded 'words', and could reproduce the same problem - only even numbered 'HazardIds' are written to the PDF. Only took a quick look, so not exactly sure whether the problem is where you're calling Go() or something else, but here's a simple working example that does what you're looking for:

Font font = FontFactory.GetFont("Arial", 20);
string word = "word word word word";
StringBuilder sb = new StringBuilder();

PdfContentByte cb = writer.DirectContent;
ColumnText ct = new ColumnText(cb);
ct.Alignment = Element.ALIGN_JUSTIFIED;

Paragraph hazardTitle = new Paragraph("Hazards", font);
hazardTitle.Alignment = Element.ALIGN_CENTER;

var pos = writer.GetVerticalPosition(false) - 40;
float gutter = 15f;
float colwidth = (doc.Right - doc.Left - gutter) / 2;
float col0right = doc.Left + colwidth;
float col1left = col0right + gutter;
float col1right = col1left + colwidth;
float[][] COLUMNS = 
{
    new float[] { doc.Left, doc.Bottom, col0right, pos },
    new float[] { col1left, doc.Bottom, col1right, pos }
};

for (int i = 1; i <= 40; ++i )
{
    ct.AddText(new Phrase(string.Format(
        "- [{0}] {1}", 
        i, sb.Append(word).ToString()
    )));
    ct.AddText(Chunk.NEWLINE);
}

int status = 0;
int column = 0;
while (ColumnText.HasMoreText(status))
{
    ct.SetSimpleColumn(
        COLUMNS[column][0], COLUMNS[column][1],
        COLUMNS[column][2], COLUMNS[column][3]
    );
    status = ct.Go();
    column = Math.Abs(column - 1);
    if (column == 0)
    {
        doc.Add(hazardTitle);
        doc.NewPage();
    }
}
// add last title if first column still has space
if (column != 0)
{
    doc.Add(hazardTitle);
}