5

Печатаем отчеты в VB.NET. Часть 2.

29 августа 2008 года

Рано или поздно вам потребуется напечатать отчет в формате какого-либо офисного приложения. Так как процент людей, пользующихся StarOffice невелик, то скорее всего это будет всеми любимый Microsoft Office. ;-)

Итак, в этой статье мы рассмотрим, как напечатать отчет в формате MS Excel (не забудьте, что для начала в проект необходимо добавить ссылку на соответствующий assembly).  Создадим процедуру, которая получает на вход какой-либо объект с данными (в нашем случае это DataGridView), генерирует на их основе ответ и выводит его на печать.  Ниже приведен пример с пояснениями:

    Private Sub ExportToExcel(ByVal dgv As DataGridView)
        Dim ObjExcel As New Microsoft.Office.Interop.Excel.Application()        ' инициализируем excel-приложение
        Dim ObjWorkBook As Microsoft.Office.Interop.Excel.Workbook            ' создаем объект книги
        Dim ObjWorkSheet As Microsoft.Office.Interop.Excel.Worksheet         ' создаем объект страницы листа 

        ObjExcel.Visible = False                                                               ' делаем приложение невидимым пользователю
        ObjWorkBook = ObjExcel.Workbooks.Add()                                      ' добавляем новую книгу в приложение
        ObjWorkSheet = ObjWorkBook.Worksheets(1)                                  ' получаем доступ к первой странице

        ObjWorkSheet.Columns(1).ColumnWidth = 20                                  ' устанавливаем ширину колонок. 

        ObjWorkSheet.Columns(2).ColumnWidth = 20
        ObjWorkSheet.Columns(3).ColumnWidth = 10
        ObjWorkSheet.Columns(4).ColumnWidth = 25
        ObjWorkSheet.Columns(5).ColumnWidth = 4
        ObjWorkSheet.Columns(6).ColumnWidth = 4
        ObjWorkSheet.Columns(7).ColumnWidth = 15
        ObjWorkSheet.Columns(8).ColumnWidth = 15

        ObjWorkSheet.Rows(1).Font.Bold = True                              
        ObjWorkSheet.Rows(1).font.size = 8                                              ' устанавливаем размер шрифта

        ObjWorkSheet.Cells(1, 1).Value = "Direct"                                       ' заполняем названия столбцов
        ObjWorkSheet.Cells(1, 2).Value = "Reverse"
        ObjWorkSheet.Cells(1, 3).Value = "Volume"
        ObjWorkSheet.Cells(1, 4).Value = "Instrument Type"
        ObjWorkSheet.Cells(1, 5).Value = "Book"
        ObjWorkSheet.Cells(1, 6).Value = "Page"
        ObjWorkSheet.Cells(1, 7).Value = "Filing Date"
        ObjWorkSheet.Cells(1, 8).Value = "Instrument Date"

        Dim i As Integer = 2
        Dim j As Integer = 0
        Dim dr As DataGridViewRow
        For Each dr In dgv.Rows                                                                  ' в цикле заполняем таблицу данными
            ObjWorkSheet.Cells(i, 1).Value = dr.Cells(  "Direct").Value
            ObjWorkSheet.Cells(i, 2).Value = dr.Cells(  "Reverse").Value
            ObjWorkSheet.Cells(i, 3).Value = dr.Cells(  "Volume").Value
            ObjWorkSheet.Cells(i, 4).Value = dr.Cells(  "InstrType").Value
            ObjWorkSheet.Cells(i, 5).Value = dr.Cells(  "Book").Value
            ObjWorkSheet.Cells(i, 6).Value = dr.Cells(  "Page").Value
            ObjWorkSheet.Cells(i, 7).Value = dr.Cells(  "FilingDate").Value
            ObjWorkSheet.Cells(i, 8).Value = dr.Cells(  "InsDate").Value
            ObjWorkSheet.Rows(i).font.size = 8
            i += 1
        Next
        ObjWorkSheet.PageSetup.Orientation = Microsoft.Office.Interop.Excel.XlPageOrientation.xlLandscape       ' изменяем ориентацию листа
        ObjWorkSheet.PrintOut()                                                                                                            ' выводим на печать
        ObjExcel.Quit()                                                                                                                         ' закрываем приложение
        ObjWorkSheet = Nothing
        ObjWorkBook = Nothing
        ObjExcel = Nothing
        GC.Collect()                                                                                                                             ' вызываем сборщик мусора
    End Sub 

Вот вообщем то и всё. О чем надо знать — нумерация строк и колонок начинается с единицы. Отсюда вытекает одна из самых распространенных ошибок — при обращении к первой ячейке (левой-верхняя) программисты используют адрес (0, 0) вместо (1, 1).  Стоит также обратить внимание на свойство Range объекта Worksheet — он позволяет получить доступ к  набору ячеек. В качестве такого набора может быть одна ячейка, целая строка, ряд или даже таблица ячеек, заданная прямоугольником. Это бывает удобно при заполнении. Из примера так же видно, что можно программно задать расположение листа на странице.  Более полный перечень настроек можно получить, обратившись к свойству PageSetup объекта Worksheet. Ну и последнее, о чем хотелось бы сказать — возможность предпросмотра, перед печатью. Для этого достаточно вызвать метод PrintPreview() того же объекта Worksheet.

93ecbad718c69d1e755026db628a5a67

Метки: , , ,

5 комментариев к записи «Печатаем отчеты в VB.NET. Часть 2.»

  1. Никита Зимин,

    Жуть какая. Такой подход чреват несовместимостью со следующей же (или предыдущей) версией Excel.
    Делайте как все нормальные люди — генерируйте HTML-файл с табличкой и сохраняйте с расширением .xls. Небольшая "шапка" позволит ему и вовсе выглядеть неотличимым от обычного эксельного файла.

  2. Konstantin Medvedev,

    Этот пример всего лишь "How to". Каким способом печатать и в какой формат экспоритровать на усмотрение программиста :-)

  3. Dmitry,

    Никита Зимин, а можно по-подробнее? Из-за может возникнуть несовместимость?

  4. ast,

    Никита Зимин,
    [cite] […]
    Делайте как все нормальные люди — генерируйте HTML-файл с табличкой и сохраняйте с расширением .xls. […][/cite]

    Я только такой подход и использовал в тех проектах, за которые отвечал ;)

  5. Виктор,

    mkp, или любой другой знающий программист в VB.NET, помогите пожалуйста решить проблему:
    Написана программа, которая выводит автоматически основываясь на БД элементы управления в определенном порядке в элементе управления "Panel", их порой очень много и они не помещаются в "Panel", естественно AutoScroll = true, но после генерации всех обьектов в "Panel" нужно вывести всё это содержимое ("Panel" =)) на печать. Проблем нет, на печать выходим, вот только печатает только то, что видно на экране, т.е. все что не вместилось осталось за скроллами, как сделать чтобы все содержимое такого элемента управления вышло на печать? даже то, что не вместилось на экран? И еще, как нарисовать в памяти ПК изображение, основанное на принципе For Each какойто обьект In группа обьектов и далее код прорисовки рисунков по данным обьектов…. Сначала получилось но не совсем так как нужно

Ответить на сообщение Dmitry