2014-11-12 2 views
0

Я хочу нарисовать расписание на основе таблицы (включая границы), где некоторые из ячеек (частично) заполнены цветом. Этот цвет основан на PdfTemplate, который добавляется как изображение в ячейку.рисовать таблицу с заполненными ячейками в PDF с помощью iText для .NET.

Я создать тестовый проект для него, и приложенных к нему размещен выходу по адресу: PDF output

В примере, я ожидаю, что это сделать заполненную строку, каждый раз в 2 кварталов больше. Как вы можете видеть, это немного больше, чем 2 блока.

Шаблон, который я создаю, должен быть точный размер ячеек таблицы. Поэтому я не понимаю, почему он становится все больше итераций.

Любые идеи, как исправить это?

public Test() 
    { 
     int cellWidth = 23; 
     int usernameCellWith = 86; 

     float[] scheduleTableColumnWidths = new float[33]; 
     scheduleTableColumnWidths[0] = usernameCellWith; 
     for (int i = 1; i <= 32; i++) 
      scheduleTableColumnWidths[i] = cellWidth; 

     using (MemoryStream stream = new MemoryStream()) 
     { 
      Rectangle rect = PageSize.GetRectangle("A4"); 
      rect = new Rectangle(rect.Height, rect.Width, 90); 
      using (Document document = new Document(rect, 10f, 10f, 10f, 10f)) 
      { 
       PdfWriter writer = PdfWriter.GetInstance(document, stream); 
       if (!document.IsOpen()) 
       { 
        document.NewPage(); 
        document.Open(); 
       } 

       PdfPTable containerTable = new PdfPTable(1); 
       containerTable.DefaultCell.Border = Rectangle.NO_BORDER; 
       containerTable.WidthPercentage = 100; 

       PdfPTable scheduleTable = new PdfPTable(scheduleTableColumnWidths); 

       for (int iRow = 0; iRow <= 23; iRow++) 
       { 
        PdfPCell usernameCell = new PdfPCell(new Phrase("user "+ iRow)); 
        usernameCell.FixedHeight = cellWidth; 
        scheduleTable.AddCell(usernameCell); 

        for (int iColumn = 1; iColumn <= 32; iColumn++) 
        { 
         PdfPCell cell = new PdfPCell(); 
         cell.FixedHeight = cellWidth; 
         if (iColumn == 1 && iRow % 2 == 0) 
         { 
          float width = (float)(iRow + 1) * cellWidth; 
          PdfTemplate template = writer.DirectContent.CreateTemplate(width, cellWidth); 
          template.SetColorFill(new BaseColor(System.Drawing.ColorTranslator.FromHtml("#255C8A"))); 
          template.Rectangle(0, 0, width, cellWidth); 
          template.Fill(); 
          cell = new PdfPCell(Image.GetInstance(template)); 
         } 
         scheduleTable.AddCell(cell); 
        } 
        scheduleTable.CompleteRow();       
       } 
       containerTable.AddCell(scheduleTable); 
       containerTable.CompleteRow(); 

       document.Add(containerTable); 
       document.CloseDocument(); 
      } 
     } 
    } 

ответ

1

Нужно ли использовать PdfTemplate? Если вы только что опубликовали упрощенную версию своего кода, он кричит, чтобы вместо этого использовать colspan, а затем iText просто вычислит все для вас.

Ниже приведена измененная версия того, что вы опубликовали. Я переместил некоторые из ваших «магических чисел» на переменные, чтобы помочь моему собственному умственному процессу. Их можно назвать не идеально, но они выполняют эту работу. Кроме того, при работе в двойном цикле for я рекомендую всегда перебирать строки и столбцы , а затем, выполняющий логику. Ваш код перебирает строки, выполняет некоторую логику для «первой ячейки», а затем перебирает подмножество столбцов и выполняет больше логики. Несмотря на то, что абсолютно достоверно на 100%, я лично считаю его запутанным, особенно когда вам приходится прыгать между 1 и 0 в качестве стартового значения.

Также, я очень рекомендую избегать CompleteRow(). Он существует, чтобы решить определенную проблему, но это также буквально означает, что «моя логика выше может быть неправильной, так что iText, вы могли бы просто погладить номера для меня?»

Я прокомментировал большую часть того, что я изменил, поэтому, надеюсь, это полезно.

public void Test() { 
    int cellWidth = 23; 
    int usernameCellWith = 86; 
    int maxNumberOfColumns = 32; 
    int maxNumberOfRows = 24; 

    float[] scheduleTableColumnWidths = new float[maxNumberOfColumns]; 
    scheduleTableColumnWidths[0] = usernameCellWith; 
    for (int i = 1; i < maxNumberOfColumns; i++) 
     scheduleTableColumnWidths[i] = cellWidth; 

    using (MemoryStream stream = new MemoryStream()) { 
     iTextSharp.text.Rectangle rect = PageSize.GetRectangle("A4"); 
     rect = new iTextSharp.text.Rectangle(rect.Height, rect.Width, 90); 
     using (Document document = new Document(rect, 10f, 10f, 10f, 10f)) { 
      PdfWriter writer = PdfWriter.GetInstance(document, stream); 

      //Unless this code is just a sample, a new document is never open and NewPage() is implied so these four lines could just be document.Open(); 
      if (!document.IsOpen()) { 
       document.NewPage(); 
       document.Open(); 
      } 

      PdfPTable containerTable = new PdfPTable(1); 
      containerTable.DefaultCell.Border = iTextSharp.text.Rectangle.NO_BORDER; 
      containerTable.WidthPercentage = 100; 

      PdfPTable scheduleTable = new PdfPTable(scheduleTableColumnWidths); 

      //Loop through each row 
      for (int iRow = 0; iRow < maxNumberOfRows; iRow++) { 

       //Loop through each column 
       for (int iColumn = 0; iColumn < maxNumberOfColumns; iColumn++) { 

        //Placeholder variable that will be instantiated within the if statements below 
        PdfPCell cell; 

        //On the first column (of every row) 
        if (0 == iColumn) { 
         cell = new PdfPCell(new Phrase("user " + iRow)); 

        //On the second column of every other row starting with the first (zeroth) row 
        } else if ((iColumn == 1) && (iRow % 2 == 0)) { 
         cell = new PdfPCell(); 
         //Have the cell span based on the current row number 
         cell.Colspan = iRow + 1; 
         //Set the color 
         cell.BackgroundColor = new BaseColor(System.Drawing.ColorTranslator.FromHtml("#255C8A")); 
         //Tell the inner for loop that we've accounted for some cells already 
         iColumn += iRow; 

        //Every other cell 
        } else { 
         cell = new PdfPCell(); 
        } 

        //This is weird 
        cell.FixedHeight = cellWidth; 

        //Regardless of the above, add a cell 
        scheduleTable.AddCell(cell); 
       } 
      } 
      containerTable.AddCell(scheduleTable); 

      document.Add(containerTable); 
      document.CloseDocument(); 
     } 
    } 
} 
+0

Я не могу использовать colspan. Строка расписания может начинаться с половины ячейки. Я не всегда должен заполнять целые ячейки. –

+0

У вас есть определенные части, например, только четверти или половинки, или это может быть довольно произвольным, как 6/17? –

+0

Это может быть что угодно. Клетка будет представлять 30 минут. Мне нужно нарисовать минутку, поэтому 1/30-я ячейка –

Смежные вопросы