Создание PDF с макетом переполнения через iTextSharp - PullRequest
1 голос
/ 14 апреля 2011

Я успешно создаю PDF-документ из DataTable через iTextSharp, но не могу получить макет в желаемом формате.

Несмотря на маловероятность, в DataTable могут использоваться десятки столбцов.Представьте себе следующую таблицу данных - каждое число представляет область, которая может поместиться на странице:

| ------------ ||1: 2: 3 || ------------ ||4: 5: 6 || ------------ |

Это должно экспортировать как 6-страничный документ PDF в порядке, который я пронумеровал разделы.Вместо этого он в настоящее время генерируется в виде двухстраничного документа с 40-ю колонками, сжатыми на каждой странице с таким маленьким шрифтом, что буквально не содержит деталей.

Самый простой способ объяснить, что я хочу, это: Когдасгенерированный PDF-файл, я хочу, чтобы он печатался как очень широкий лист Excel, а не сжимал все содержимое вместе.

Мой код выглядит следующим образом:

    public static void ExportAsPDF(DataTable Table, IList<string> Columns, string filename)
    {
        int ColumnCount = Table.Columns.Count;
        int RowCount = Table.Rows.Count;

        iTextSharp.text.Table BodyTable = new iTextSharp.text.Table(ColumnCount, RowCount);
        BodyTable.AutoFillEmptyCells = true;

        foreach (string s in Columns)
        {
            BodyTable.AddCell(s);
        }
        foreach (object o in from DataRow row in Table.Rows from o in row.ItemArray select o)
        {
            BodyTable.AddCell(o.ToString());
        }

        Document doc = new Document();
        PdfWriter.GetInstance(doc, HttpContext.Current.Response.OutputStream);
        doc.Open();
        doc.Add(BodyTable);
        doc.Close();

        HttpContext.Current.Response.ContentType = "application/pdf";
        HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.pdf", filename));
        HttpContext.Current.Response.End(); 
    }

Весь вводи помощь очень ценится.Спасибо

1 Ответ

3 голосов
/ 15 апреля 2011

Хорошо, два варианта.

  1. Нарисуйте все вручную с помощью PdfContentByte и ColumnText для части макета текста.

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

Сначала вам нужно определить страницу, которая в 3 раза шире, чем обычно.

Rectangle triplePageRect = new Rectangle(PageSize.LETTER);
float origWidth = triplePageRect.getWidth();
triplePageRect.setWidth(origWidth * 3f);

Document doc = new Document(triplePageRect);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(doc, baos);

Затем вы рисуете свою таблицу почти так же, как сейчас ... НО вы должны быть уверены, что край столбца совпадает с двумя краями страницы, чтобы вы могли легко разбить страницы позже. Бонусные баллы, если вы можете создать пустую строку с центром в месте разрыва страницы, чтобы у вас было поле.

//Your Code Here

Наконец, вам нужно сохранить PDF, открыть его снова и нарезать на ленты. Я думаю, что PdfStamper.

// write everything out to the baos.
doc.close(); 

// and suck it right back up again.  Hurray for efficiency.  Or something.
PdfReader reader = new PdfReader(baos.toByteArrayOrWhateverItsCalled());
PdfStamper stamper = new PdfStamper( reader, new FileOutputStream(outputPath));

// duplicate the pages.  I'll assume only one page, but you'll get the idea.
PdfDictionary origPage = reader.getPageN(1);
for (int i = 0; i < 2; ++i) {
  // initial size is irrelevant, we're going to change it, but !null
  stamper.insertPage(2+i, PageSize.LETTER); 
  PdfDictionary newPageDict = reader.getPage(2 + i);

  // copy the original page... note that this is a shallow copy
  newPageDict.putAll(origPageDict);

  // duplicate the page rect so each page will have its own copy
  PdfArray pageRect = newPageDict.getAsArray(PdfName.MEDIABOX);
  // also a shallow copy, but changes to this array will be localized to the page.
  PdfArray newRect = new PdfArray(pageRect);
  // page rects are defined as [llx lly urx ury], so we need to change 0 and 2.
  newRect.set(0, new PdfNumber(origWidth * (i+1));
  newRect.set(2, new PdfNumber(origWidth * (i+2));
}

//Smoke'em if you've got 'em folks, we're done.
stamper.close();

Черт, я в порядке. Ооо ооо И скромный! Давайте не будем забывать, красивый, смелый, вежливый, остроумный ...

...