Лекция № 15
Тема: «Создание отчетов по базе данных в Word »
План
1. Общие принципы технологии COM
2. Работа с COM-сервером Microsoft Word
3. Работа с документами в Microsoft Word
4. Использование закладок для формирования документов
5. Работа с таблицами
6. Вставка рисунков и их форматирование
1. Общие принципы технологии COM
Одной из особенностей многозадачных операционных систем является поддержка взаимодействия и обмена информацией между различными программами. Операционная система Windows - не исключение из этого правила и предоставляет множество механизмов такой поддержки. Работа ОС Windows предусматривает передачу и обработку сообщений как между ОС и приложением, так и между приложениями, а также использование динамических библиотек. Этот механизм был использован еще в первых версиях Windows и отразился на методах разработки приложений для этой ОС. С развитием операционной системы развивались и механизмы взаимодействия программ. На первый план вышла необходимость управления целыми объектами, которые представляют собой приложения или документы. Такая постановка задачи вызвала революционные изменения как в структуре ОС Windows, так и в программах, предназначенных для разработки приложений. Приложения MS Office представляют собой объекты-серверы, которые могут управляться внешними программами, и здесь не последнюю роль играют механизмы СОМ и OLE.
Модель СОМ предоставляет возможность создания многократно используемых объектов в различных приложениях, поддерживающих этот интерфейс. Объектами СОМ являются приложения-серверы, специальным образом оформленные и зарегистрированные в системе. Они могут быть представлены в формате ЕХЕ или DLL-модулей. Эти серверы могут загружаться и выполняться как в адресном пространстве вызывающего их приложения, так и в виде самостоятельного процесса. Они могут быть написаны на любом языке, который поддерживает интерфейс СОМ.
Сервер автоматизации представляет собой программу, которая может управляться внешней программой - контроллером автоматизации. Сервером в этом случае является приложение, например Word или Excel, а контроллером автоматизации - программа, которая "умеет" управлять приложениями MS Office и процессом создания документов в среде Word и Excel.
Технология .NET поддерживает модель COM для управления другими приложениями.
Если говорить о создании отчетов по БД, то наиболее оптимальным вариантом является тот, при котором сам отчет будет строиться в какой-то внешней программе, где пользователь сможет полученный документ просмотреть и распечатать, а при необходимости отредактировать и сохранить. Если учитывать навыки большинства пользователей ПК, то наиболее естественными программами, в формате которых должны строиться отчеты по БД, естественно, могут выступать программы из пакета Microsoft Office: Word или Excel.
2. Работа с COM-сервером Microsoft Word
Для работы с COM сервером Microsoft Word в среде Visual Studio на языке программирования C# необходимо выполнить ряд действий.
Вначале подключите пространства имен:
using Word = Microsoft.Office.Interop.Word;
using System.Reflection;
using System.Runtime.InteropServices;
Затем нужно подключить динамическую. библиотеку программы
Кроме этого нужно подключить COM библиотеку программы Microsoft Word.
Для этого в контекстном меню проекта выберите команду "Добавить ссылку". В новом окне перейдите на закладку COM и выберите элемент с именем "Microsoft Word XX Object Library", где ХХ - номер версии Word (на разных компьютерах номер XX может быть разным, в зависимости от установленной версии пакета Microsoft Office).

На рисунке в списке отображается две библиотеки версии 11.0 и 14.0. Это говорит о том, что на компьютере установлено несколько версий Microsoft Word. Чаще всего такая библиотека одна. Выбирайте версию с большим номером (более новая).
В результате в панели "Обозреватель решений" в папке "Ссылки" появится элемент "Microsoft.Office.Interop.Word".

Далее нужно описать глобальную переменную для получения ссылки на запущенный экземпляр Microsoft Office и работы с ним.
//описываем переменную w типа Word.Application
Word.Application w;
После описания переменной можно создать новый объект COM-сервера с помощью команды:
w = new Word.Application();
После выполнения этого оператора приложение Word запустится, но его окно не появится на экране монитора. В диспетчере задач в списке процессов можно увидеть, что процесс Winword.exe запущен и находится в памяти компьютера.
Чтобы окно программы стало видимой, необходимо установить следующее свойством:
w.Visible=true;
При формировании документов, рекомендуется свойство Visible включать после окончания формирования документа. Так можно повысить производительность работы приложения, так как не будут тратиться ресурсы компьютера на отображение на монитора самого процесса построения документа. При этом, пока документ строится, процесс можно сопровождать отображением заполняющего индикатора до 100%.
Запуск или подключения к Word
Мы рассмотрели пример создания нового объекта для запуска копии Microsoft Word. Однако такой подход имеет недостаток: если Word уже будет запущен пользователем, то создание нового экземпляра с помощью метода new Word.Application() запустит новую копию программы, что ведет к нерациональному расходу оперативной памяти компьютера. Для решения данной проблемы нужно иметь в виду, что есть функция, которая не создает объект, а подключается к уже запущенной копии:
w = Marshal.GetActiveObject ("Word.Application") as Word.Application;
Перед использованием COM-сервера Word целесообразно выполнять подключение или создание объекта в зависимости от состояния программы Word. Правильный код при обращении к Word следующий:
//пытаемся подключиться к запущенному Word
try
{
w = Marshal.GetActiveObject ("Word.Application") as Word.Application;
}
//если Word на запущен, запускаем его
catch (COMException err)
{
w = new Word.Application();
}
3. Работа с документами в Microsoft Word
Итак, объект Word загружен, и у нас есть доступ к нему через переменную w. Объект имеет методы, с помощью которых можно создавать, открывать и сохранять документы.
Создание документа
Для создания документа используют метод:
w.Documents.Add();
После выполнения этого метода будет создан документ на основании стандартного шаблона Normal.dot.
Вызвать метода Add() можно с аргументом. В этом случае создается документ на основе указанного шаблона. Для своих приложений можно создать дополнительные шаблоны документов, например шаблон формы платежного поручения или налоговой декларации. В дальнейшем, используя метод Add() с указанием шаблон, легко создать нужный документ, заполняемый нужной информацией. Использование шаблонов при формировании новых документов позволит создавать гибкие и удобные для пользователя приложения.
Пример. Пусть в папке с программой есть папка шаблонов с именем Templates, а в ней файл шаблона с именем Anketa.dot. Создадим новый документ на основе шаблона.
w.Documents.Add(Application.StartupPath + "\\Templates\\Anketa.dot");
Сохранение документа
Можно программно сохранить созданный документ на диск. Для этого используется метод вида:
w.ActiveDocument.SaveAs("имя_файла" [, null , null, "пароль"]);
Метод имеет аргументы:
· имя_файла - имя файла;
· пароль - пароль для защиты файла.
Например, пусть в папке с программой имеется вложенная папка Docs. Сохраним документ в эту папку в формате Word под именем Report.doc.
w.ActiveDocument.SaveAs(Application.StartupPath + "\\Docs\\Report.doc");
Сохраним файл еще раз, но с заданием пароля для защиты файла.
w.ActiveDocument.SaveAs(Application.StartupPath + "\\Docs\\Report.doc", null, null, "111");
Открытие файла
Для открытия файла используют метод вида:
w.Documents.Open("имя_файла" [,null, null, null, "пароль"]);
Метод имеет аргументы:
· имя_файла - имя файла;
· пароль - пароль на открытие файла.
Например: откроем сохраненный ранее файл:
w.Documents.Open(Application.StartupPath + "\\Docs\\Report.doc");
Если файл имеет пароль, то его можно открыть так:
w.Documents.Open(Application.StartupPath + "\\Docs\\Report.doc", null, null, null, "111");
Закрытие документа и приложения Word
Если документ сохранен, то его можно закрыть с помощью метода:
w.ActiveDocument.Close();
После закрытия документа, можно закрыть и само приложение Word. Для этого используют два оператора:
w.Quit();
w=null;
Используя методы работы с документами, можно организовывать фоновое создания файлов без отображения их на экране.
Пример. На основании шаблона Anketa.dot из папки Templates создать новый документ. Сохранить документ под именем Report.doc в папку Docs. После сохранения выдать сообщение об успешном создании файла и предложить пользователю показать файл для просмотра. Если ответ положительный, то файл открывается, если отрицательный, то Word закрывается.
//создаем объект (запускаем Word)
w = new Word.Application();
//создаем новый документ на основе шаблона
w.Documents.Add(Application.StartupPath + "\\Templates\\Anketa.dot");
//сохраняем документ в указанный файл в формате doc
w.ActiveDocument.SaveAs(FileName=Application.StartupPath + "\\Docs\\Report.doc", FileFormat=1);
//выдаем запрос на открытие сохраненного файла
if (MessageBox.Show("Файл сохранен. Показать? ",
"Запрос",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question)==DialogResult.Yes)
//если ответ Да, делаем Word видимым
w.Visible=true;
else
//если ответ Нет, закрываем документ в Word
{
w.ActiveDocument.Close();
w.Quit();
w=null;
};
4. Использование закладок для формирования документов
Шаблоны является самым удобным способом формирования документов Word. Разработчик может создать целую коллекцию шаблонов, в которых задать расположение текстовых блоков и их форматирования. Шаблон может содержать как постоянные элементы, так и элементы-переменные, на место которых будет подставляться другой текст при формировании документа. Такие переменные должны иметь какие-то уникальные в пределах шаблона имена (например: # fam #, # imya #, # otch # и т.п.) и быть оформлены в виде закладок.
Закладка – это текстовое обозначение фрагмента текста в документе. Программа может найти по имени данный фрагмент, обратиться к нему и заменить на нужную информацию. Для создания закладки выделите фрагмент, который является переменной, и выполните команду Вставка – Закладка. В окне введите имя закладки и щелкните на кнопке Добавить. Для обращения к нужной закладке в коде используют команду вида:
w.ActiveDocument.Bookmarks["имя_закладки"].Range.Text=значение;
Например, пусть в шаблоне Anketa.dot из папки Templates имеются закладки с именами: fam, imya, otch. Необходимо на их место подставить значения Иванов, Иван, Иванович.
//пытаемся подключиться к запущенному Word
try
{
w = Marshal.GetActiveObject ("Word.Application") as Word.Application;
}
//если Word на запущен, запускаем его
catch (COMException err)
{
w = new Word.Application();
}
//создаем новый документ на основе шаблона
w.Documents.Add(Application.StartupPath + "\\Templates\\Anketa.dot");
// заменяем закладку fam на Иванов
w.ActiveDocument.Bookmarks["fam"].Range.Text="Иванов";
// заменяем закладку imya на Иван
w.ActiveDocument.Bookmarks["imya"].Range.Text="Иван";
// заменяем закладку otch на Иванович
w.ActiveDocument.Bookmarks["otch"].Range.Text="Иванович";
// делаем документ видимым
w.Visible=true;
Вместо значений в шаблон можно подставлять не только конкретные значения, но и содержимое полей БД. Такой подход позволяет создавать отчеты по БД с экспортом их в Word.
Пример. Пусть в шаблоне Anketa.dot из папки Templates имеются закладки: fam, imya, otch, datar. Необходимо на их место подставить значения полей fam, tab, otch, datar из текущей записи набора данных sotrBindingSource.
Для построения отчета напишем код:
//пытаемся подключиться к запущенному Word
try
{
w = Marshal.GetActiveObject ("Word.Application") as Word.Application;
}
//если Word на запущен, запускаем его
catch (COMException err)
{
w = new Word.Application();
}
//создаем новый документ на основе шаблона
w.Documents.Add(Application.StartupPath + "\\Templates\\Anketa.dot");
// заменяем закладку fam на поле fam
w.ActiveDocument.Bookmarks["fam"].Range.Text=(sotrBindingSource.Current as DataRowView)["fam"].ToString();
// заменяем закладку imya на поле imya
w.ActiveDocument.Bookmarks["imya"].Range.Text=(sotrBindingSource.Current as DataRowView)["imya"].ToString();
// заменяем закладку otch на поле otch
w.ActiveDocument.Bookmarks["otch"].Range.Text=(sotrBindingSource.Current as DataRowView)["otch"].ToString();
// заменяем закладку datar на поле datar
w.ActiveDocument.Bookmarks["datar"].Range.Text=(sotrBindingSource.Current as DataRowView)["datar"].ToString();
// делаем документ видимым
w.Visible=true;
Пример. Пусть на форме отобраны нужные записи (для набора данных sotrBindingSource выполнена фильтрация). Необходимо для каждой отобранной записи сформировать свой отдельный файл на основании шаблона Anketa.dot.
Процесс построения отчета будем сопровождать заполнением строки индикатора до 100%. Нанесите на форме компонент ProgressBar и задайте свойство Visible=false (сделайте невидимым).
//сбрасываем значение индикатора в 0
progressBar1.Value = 0;
//задаем максимальное значение индикатора
//общее число записей + 1
progressBar1.Maximum = sotrBindingSource.Count + 1;
//делаем индикатор видимым
progressBar1.Visible = true;
//пытаемся подключиться к запущенному Word
try
{
w = Marshal.GetActiveObject ("Word.Application") as Word.Application;
}
//если Word на запущен, запускаем его
catch (COMException err)
{
w = new Word.Application();
}
//наращиваем значение индикатора на 1
progressBar1.Value++;
// становимся на первую найденную запись
sotrBindingSource.MoveFirst();
// в цикле проходим по всем найденным записям
foreach (DataRowView row in sotrBindingSource)
{
//создаем новый документ на основе шаблона
w.Documents.Add(Application.StartupPath + "\\Templates\\Anketa.dot");
// заменяем закладку fam на поле fam
w.ActiveDocument.Bookmarks["fam"].Range.Text=row["fam"].ToString();
// заменяем закладку imya на поле imya
w.ActiveDocument.Bookmarks["imya"].Range.Text=row["imya"].ToString();
// заменяем закладку otch на поле otch
w.ActiveDocument.Bookmarks["otch"].Range.Text=row["otch"].ToString();
// заменяем закладку datar на поле datar
w.ActiveDocument.Bookmarks["datar"].Range.Text=row["datar"].ToString();
//наращиваем значение индикатора на 1
progressBar1.Value++;
};
//скрываем индикатор
progressBar1.Visible = false;
// делаем документ видимым
w.Visible=true;
5. Работа с таблицами
Рассмотренный выше способ работы с шаблонами подходит для формирования отчета по одной записи таблицы БД.
Чаще приходится формировать отчеты по набору записей. В этом случае такой набор отображается в виде таблицы, в каждой строке которой находится информация об отдельной записи.
Формирование такого документа можно выполнять с помощью шаблона, в котором нужно подготовить только шапку таблицы, задав нужную ширину колонок, выравнивание и формат символов.
Для работы с таблицей имеется большой набор методов и свойств. Для формирования отчетов рассмотрим некоторые из них.
Для обращения к таблице используют запись:
w.ActiveDocument.Tables[i]
где i - номер таблицы (нумерация начинается с 1)
Обратиться к строке таблицы можно с помощью записи:
w.ActiveDocument.Tables[i].Rows[j]
где i - номер таблицы (нумерация начинается с 1)
j - номер строки (нумерация с 1).
Обратиться к колонке таблицы можно с помощью записи:
w.ActiveDocument.Tables[i].Columns[j]
где i - номер таблицы (нумерация начинается с 1;)
j - номер столбца (нумерация с 1).
Обратиться к ячейке таблицы можно с помощью записи:
w.ActiveDocument.Tables[i].Rows[j].Cells[m]
где i - номер таблицы (нумерация начинается с 1)
j - номер строки (нумерация с 1).
m - номер колонки в строке (нумерация с 1).
Обратиться к тексту ячейки таблицы можно с помощью записи:
w.ActiveDocument.Tables[i].Rows[j].Cells[m].Range.Text
Для добавления строки в конец таблицы используют команду:
w.ActiveDocument.Tables[i].Rows.Add();
Узнать количество строк или столбцов в таблице можно с помощью свойства:
w.ActiveDocument.Tables[i].Rows.Count
w.ActiveDocument.Tables[i].Columns.Count
На основании этих свойств и методов можно сформировать табличный документ.
Пример. Пусть в папке Templates имеется шаблон List.dot. Шаблон имеет шапку таблицы с заголовками столбцов: № п/п, Фамилия, Имя, Отчество, Дата рождения. Необходимо в документе отразить данные из таблицы БД. Для этого напишем код:
//сбрасываем значение индикатора в 0
progressBar1.Value = 0;
//задаем максимальное значение индикатора
//общее число записей + 1
progressBar1.Maximum = sotrBindingSource.Count + 1;
//делаем индикатор видимым
progressBar1.Visible = true;
//пытаемся подключиться к запущенному Word
try
{
w = Marshal.GetActiveObject ("Word.Application") as Word.Application;
}
//если Word на запущен, запускаем его
catch (COMException err)
{
w = new Word.Application();
}
//создаем новый документ на основе шаблона
w.Documents.Add(Application.StartupPath + "\\Templates\\list.dot");
//наращиваем значение индикатора на 1
progressBar1.Value++;
//становимся на первую найденную запись
sotrBindingSource.MoveFirst();
//счетчик строк в таблице (у нас в шаблоне имеется шапка, поэтому строк 1)
int r = 1;
//в цикле проходим по всем найденным записям
foreach (DataRowView row in sotrBindingSource)
{
//добавляем новую строку в таблицу
w.ActiveDocument.Tables[1].Rows.Add();
//наращиваем количество строк
r++;
//в каждую ячейку i-й строки таблицы записываем значения поля запроса
//в первой ячейке отображаем № п/п
w.ActiveDocument.Tables[1].Rows[r].Cells[1].Range.Text = (r-1).ToString();
//во второй ячейке отображаем фамилию
w.ActiveDocument.Tables[1].Rows[r].Cells[2].Range.Text = row["fam"].ToString();
//в третьей ячейке отображаем имя
w.ActiveDocument.Tables[1].Rows[r].Cells[3].Range.Text = row["imya"].ToString();
//в четвертой ячейке отображаем отчество
w.ActiveDocument.Tables[1].Rows[r].Cells[4].Range.Text = row["otch"].ToString();
//наращиваем значение индикатора
progressBar1.Value++;
};
//скрываем индикатор
progressBar1.Visible = false;
//делаем документ видимым
w.Visible = true;
Форматирование таблицы
Таблицу можно отформатировать, задав ей тип, толщину и цвет линии границы, а также цвет фона и параметры шрифта.
Каждый элемент таблицы: сама таблицы, строка, столбец, ячейка обладают рядом свойств для форматирования:
Borders. OutsideLineWidth = Word.WdLineWidth.значение; //ширина внешней границы;
Borders.OutsideColorIndex = Word.WdColorIndex.значение; //цвет линии внешней границы;
Borders.OutsideLineStyle = Word.WdLineStyle.значение; //тип линии внешней границы;
Borders. InsideLineWidth = Word.WdlineWidth.значение; //ширина внутренней границы;
Borders.InsideColorIndex = Word.WdColorIndex.значение; //цвет линии внутренней границы;
Borders.InsideLineStyle = Word.WdLineStyle.значение; //тип линии внутренней границы;
Shading.BackgroundPatternColorIndex = Word.WdColorIndex.значение; //цвет фона.
Пример. Изменим предыдущий пример. В конец построенной таблицы добавьте еще одну строку. В предпоследний ячейке этой строки нужно отобразить текст «Всего», а в последний ячейке отразить сумму окладов по предприятию. Сумма окладов рассчитывается с помощью запроса.
При этом добавленная строка обрамляется толстой сплошной линией синего цвета и заливается серым цветом.
В панели "Источники данных" щелкните на кнопке "". В окне со структурами таблиц щелкните правой кнопкой на пустом месте окна и выберите команду "Добавить - Table Adapter" и введите текст запроса
select sum(oklad) as sumoklad from sotr
Переименуйте созданную таблицу в calc.
Добавьте на форму созданную таблицу calc с помощью сетки DataGridView. В результате появится два компонента calcTableAdapter и `.
В событии Load формы вызов метода
calcTableAdapter.Fill...
перенесите ниже от команды подстановки пароля в строку подключения к БД.
//ниже от кода построения таблицы добавьте команды
//если данные в наборе данных отфильтрованы (Filter не пустой или не null)
if (sotrBindingSource.Filter != "" && sotrBindingSource.Filter!=null)
//задаем запрос на расчет с учетом условия фильтрации
calcTableAdapter.Adapter.SelectCommand.CommandText = "select sum(oklad) as sumoklad from sotr where " + sotrBindingSource.Filter;
//если данные в наборе данных не отфильтрованы
else
//задаем запрос на расчет по всей таблице без условия
calcTableAdapter.Adapter.SelectCommand.CommandText = "select sum(oklad) as sumoklad from sotr";
//выполняем запрос
calcTableAdapter.Fill(sotrDataSet.calc);
//в таблицу отчета добавляем новую строку
w.ActiveDocument.Tables[1].Rows.Add();
//наращиваем количество строк
r++;
//в предпоследней ячейке строки отображаем текст
w.ActiveDocument.Tables[1].Rows[r].Cells[3].Range.Text = "Всего:";
//в последней ячейке строки отображаем поле sumoklad из запроса
w.ActiveDocument.Tables[1].Rows[r].Cells[4].Range.Text = (calcBindingSource.Current as DataRowView)["sumoklad"].ToString();
//задаем серый фон для последней строки
w.ActiveDocument.Tables[1].Rows[r].Shading.BackgroundPatternColorIndex = Word.WdColorIndex.wdGray25;
//задаем толщину линии для последней строки
w.ActiveDocument.Tables[1].Rows[r].Borders.OutsideLineWidth = Word.WdLineWidth.wdLineWidth150pt;
//скрываем индикатор
progressBar1.Visible = false;
//делаем документ видимым
w.Visible = true;
Пример. Добавим в рассмотренный выше код, который закрашивает четные строки таблицы заданным цветом.
//запускаем цикл со второй строки (без шапки таблицы)
//до предпоследней строки (без итоговой строки с суммой окладов)
for (int i = 2; i <= w.ActiveDocument.Tables[1].Rows.Count - 1; i++)
//нужно закрашивать четные строки, но их номера в таблице нечетные
//например, у записи № п/п = 2, а фактически номер строки в таблице = 3 и.д.
//если номер строки нечетный (остаток отделения на 2 не 0)
if (i % 2 != 0)
//закрашивыаем строку с эти номером заданным цветом
w.ActiveDocument.Tables[1].Rows[i].Shading.BackgroundPatternColorIndex = Word.WdColorIndex.wdTeal;
6. Вставка рисунков и их форматирование
Кроме текста и таблиц документы могут включать графические элементы - рисунки. Для вставки рисунка в документ используют метод:
w.ActiveDocument.Range.InlineShapes.AddPicture("имя_файла");
Данный метод позволяет вставить указанный рисунок в место положения курсора. Если же нужно, чтобы рисунок появился в нужном место, то целесообразно вставлять рисунок в ячейку таблицы, которая должна быть предварительно создана в файле шаблона. Вставка рисунка в ячейку таблицы выполняется с помощью метода:
w.ActiveDocument.Tables[i].Cell[n, m].Range.InlineShapes.AddPicture("имя_файла");
Вставленный рисунок по умолчанию имеет оригинальный размер. Для задания нужного размера рисунка используют свойства:
w.ActiveDocument.InlineShapes[i].Width=число;
w.ActiveDocument.InlineShapes[i].Height=число;
где i - номер рисунка в документе (нумерация с 1).
Рассмотренный способ предполагает, что вставляемый рисунок хранится на диске в виде файла. Если при построении отчета по таблице БД каждое изображение из поля будет вначале сохраняться на диск, а затем вставляться в отчет, то процесс формирования отчета может занять много времени, так как работа с диском намного медленнее, чем работа с ОЗУ. Наиболее быстрым способом является такой, при котором изображение из поля таблицы БД считывается в ОЗУ и сразу помещается в отчет без участия жесткого диска.
Пример. Пусть в таблице БД имеется поле foto. Нужно создать документ на основании шаблона List.dot из папки Templates, в котором в виде таблицы выдать поля fam, imya, otch и foto.
//переменные для чтения фото из БД
Byte[] blob = null;
MemoryStream memStream = null; //подключите System.IO
Image img =null;
//сбрасываем значение индикатора в 0
progressBar1.Value = 0;
//задаем максимальное значение индикатора
//общее число записей + 1
progressBar1.Maximum = sotrBindingSource.Count + 1;
//делаем индикатор видимым
progressBar1.Visible = true;
//пытаемся подключиться к запущенному Word
try
{
w = Marshal.GetActiveObject ("Word.Application") as Word.Application;
}
//если Word на запущен, запускаем его
catch (COMException err)
{
w = new Word.Application();
}
//создаем новый документ на основе шаблона
w.Documents.Add(Application.StartupPath + "\\Templates\\list.dot");
//наращиваем значение индикатора на 1
progressBar1.Value++;
//становимся на первую найденную запись
sotrBindingSource.MoveFirst();
//счетчик строк в таблице (у нас в шаблоне имеется шапка, поэтому строк 1)
int r = 1;
//счетчик картинок в отчете
int k = 0;
//в цикле проходим по всем найденным записям
foreach (DataRowView row in sotrBindingSource)
{
//добавляем новую строку в таблицу
w.ActiveDocument.Tables[1].Rows.Add();
//наращиваем количество строк
r++;
//в каждую ячейку i-й строки таблицы записываем значения поля запроса
//в первой ячейке отображаем № п/п
w.ActiveDocument.Tables[1].Rows[r].Cells[1].Range.Text = (r-1).ToString();
//во второй ячейке отображаем фамилию
w.ActiveDocument.Tables[1].Rows[r].Cells[2].Range.Text = row["fam"].ToString();
//в третьей ячейке отображаем имя
w.ActiveDocument.Tables[1].Rows[r].Cells[3].Range.Text = row["imya"].ToString();
//в четвертой ячейке отображаем отчество
w.ActiveDocument.Tables[1].Rows[r].Cells[4].Range.Text = row["otch"].ToString();
//выводим поле foto
//если поле foto не пустое
if (row["foto"].ToString()!="")
{
//считываем содержимое поля
blob = (byte[])row["foto"];
//выделяем в памяти буфер размером в поле foto
memStream = new MemoryStream(blob);
//считываем поле foto в буфер памяти
memStream.Write(blob, 0, blob.Length);
memStream.Position = 0;
//в переменную помещаем содержимое буфера памяти (конвертируем в графику)
img= Image.FromStream(memStream);
//копируем в буфер изображение
Clipboard.SetImage(img);
//в r-ю строку 5 колонку таблицы вставляем содержимое буфера
w.ActiveDocument.Tables[1].Rows[r].Cells[5].Range.Paste();
//наращиваем количество картинок
k++;
//для k-й картинки задаем ширину и высоту
w.ActiveDocument.InlineShapes[k].Width=50;
w.ActiveDocument.InlineShapes[k].Height=60;
}
//наращиваем значение индикатора
progressBar1.Value++;
};
//скрываем индикатор
progressBar1.Visible = false;
//делаем документ видимым
w.Visible = true;
Вопросы для самоконтроля
1. Опишите общие понятия технологии COM.
2. Опишите принципы работы с COM сервером Microsoft Word. Приведите пример кода, который подключается к запущенному экземпляра Word или запускает его.
3. Опишите принципы работы с документами Word.
4. Опишите принципы формирования отчета в Word с помощью закладок.
5. Какие свойства и методы объекта Word вы знаете для формирования табличных документов?
6. Как вставить изображение в документ Word?