Модификация приложения Windows Forms : создание и заполнение нового документа Microsoft Word



 

Что представляет из себя полная автоматизация документа? Заполнение документа и всех важных полей, например фамилий, дат и названий. Разумеется, для редактирования правописания или более глубокого изменения документа надо использовать сам Word. Автоматизация части документа подходит в основном для рутинного заполнения однотипных документов, будь то всякие бланки или ведомости... Применений можно найти массу.

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

 

Для начала изменим размер нашей единственной формы. Для этого можно потянуть за уголок в нужном направлении на странице визуального представления формы1. Но также размер можно менять на панели свойств этой формы. Для этого нужно поменять значение размера в пикселях (высоту и ширину) в поле Size.

 

ПРИМЕЧАНИЕ № 1: Для перехода на визуальное представление формы, необходимо двойным нажатием в обозревателе решений нажать на значок формы ( ) или выбрать вкладку на панели вкладок с именем <имя формы>. cs [Конструктор].

 

Задаём следующие параметры формы на панели Свойства:

 

( Name ) изменим с Form 1. cs 2 на LWP 12 Main

^ Поменяем внутреннее имя формы.

Text изменим с Form 1 на Автоматизация Microsoft Office Word ( C #)

^ Поменяем заголовок формы (то что отображается в шапке приложения слева).

Icon изменим изображение (иконку) приложения

^ Необходим файл значка *. ico.

Size изменим со значений 300; 300 на 5 00; 315

^ Поменяем размер формы.

 

ПРИМЕЧАНИЕ № 2: Для того, чтобы поменять имя файла нашей формы, необходимо выполнить следующее: выделить в обозревателе решений значок формы ( ) и нажать правую кнопку мыши, затем выбрать Переименовать. Ввести необходимое новое имя, СОХРАНЯЯ расширение *. cs. После смены имени, автоматически поменяются имена проассоциированных непосредственно с формой файлов:

 

Также, разместим первую группу элементов для работы с автоматическим созданием нового документа. Получим нечто подобное:

 

Рис. 3. 1. Модифицированная форма приложения и расстановка первой группы элементов

 

Здесь у нас семь кнопок Button, один GroupBox, один OpenFileDialog и один NumericUpDown.

 

По порядку распишем Свойства каждого элемента:

 

Button:

(Name): B_Open
Text: Открыть Word, создать документ
Size: 200; 23

Button:

(Name): B_Page_1
Text: Страница № 1
Size: 100; 23

Button:

(Name): B_Page_2
Text: Страница № 2
Size: 200; 23

GroupBox:

(Name): GB_1
Text: Автоматическое создание и заполнение нового документа

Button:

(Name): B_Print
Text: Печать
Size: 100; 23

Button:

(Name): B_Scale
Text: Масштаб
Size: 100; 23

Button:

(Name): B_Numeric
Text: Пронумеровать страницы
Size: 200; 23

Button:

(Name): B_Picture
Text: Вставить рисунок
Size: 200; 23

NumericUpDow:

(Name): NUD_Scale
Text: Increment
Size: 25
Minimum: 25
Maximum: 200

OpenFileDialog:

(Name): OFD_Picture
Filter: Файлы JPEG|*.jpg
DefaultExt: jpg
FileName: Рисунок для Word

 

Также, нам необходимо добавить связь приложения и библиотеку компонентов и объектов самого Word. Для этого выполним следующее: Проект -> Добавить ссылку. В открывшемся окне выбираем COM, далее ищем Microsoft Word 14.0 Object Library (для Word 2010) и Microsoft Word 12.0 Object Library (для Word 2007):

 

Рис. 3. 2. Добавить ссылку: добавление библиотеки компонентов от Word 2010

 

В случае наличия на «машине» только Word 2007, при сборке приложения необходимо добавить библиотеку «12-ой» версии. Если же установлено две версии (2007 и 2010), то необходимо добавлять библиотеку той версии, что является активной в данный момент (при запуске не производит действий по перенастройке пакета установки).

 

Теперь отправляемся в код формы (правая кнопка мыши на значке формы, далее Перейти к коду или нажмём на клавишу F 7).

 

Найдём:

 

public partial class LWP12Main : Form

{

 

Добавим после:

 

   object oMissing = System.Reflection.Missing.Value;

   object oEndOfDoc = "\\endofdoc"; // \endofdoc - предустановленная закладка

   // Запускаем Word и создаём новый документ

   Word._Application oWord;

   Word._Document oDoc;

 

Изменим следующую функцию LWP12Main():

 

   public LWP12Main()

   {

       InitializeComponent();

       B_Page_1.Enabled = false;

       B_Page_2.Enabled = false;

       B_Print.Enabled = false;

       B_Number.Enabled = false;

       B_Scale.Enabled = false;

       B_Picture.Enabled = false;

   }

 

Событие Click кнопки B_Open («Открыть Word, создать документ»):

 

   private void B_Open_Click(object sender, EventArgs e)

   {

       B_Open.Enabled = false;

       oWord = new Word.Application(); // Запускаем Word

       oWord.Visible = true; // Делаем окно Word видимым

       // Старый способ: здесь отражено наличие ключевого слова ref и параметра oMissing, которые можно не использовать

       oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing); // Создаём новый документ

       B_Page_1.Enabled = true;

       B_Print.Enabled = true;

       B_Number.Enabled = true;

       B_Scale.Enabled = true;

       B_Picture.Enabled = true;

   }

 

Событие Click кнопки B_Page_1 («Страница № 1»):

 

   private void B_Page_1_Click(object sender, EventArgs e)

   {

       // Вставка текста в начало документа и отступа после

       Word.Paragraph oPara1;

       // Стары способ

       //oPara1 = oDoc.Content.Paragraphs.Add(ref oMissing);

       oPara1 = oDoc.Content.Paragraphs.Add();

       oPara1.Range.Text = "Заголовок № 1 с тенью";

       oPara1.Range.Font.Size = 20; // Размер шрифта: 20

       oPara1.Range.Font.Shadow = 1; // Тенью от шрифта

       oPara1.Range.Font.Bold = 1; // "Жирный" шрифт

       oPara1.Format.SpaceAfter = 24; // 24 пт.: оступ после параграфа

       oPara1.Range.InsertParagraphAfter();

       oPara1.Range.Font.Size = 12; // Размер шрифта: 12

       oPara1.Range.Font.Shadow = 0; // Тенью от шрифта: выключаем

 

       // Вставка текста и отступа после (для последующих частей документа)

       Word.Paragraph oPara2;

       object oRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       oPara2 = oDoc.Content.Paragraphs.Add(ref oRng);

       oPara2.Range.Text = "Заголовок № 2";

       oPara2.Format.SpaceAfter = 6; // Отступ после

       oPara2.Range.InsertParagraphAfter();

 

       // Вставка текста

       Word.Paragraph oPara3;

       oRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       oPara3 = oDoc.Content.Paragraphs.Add(ref oRng);

       oPara3.Range.Text = "Обычный текст. Дальше идёт таблица:";

       oPara3.Range.Font.Bold = 0;

       oPara3.Format.SpaceAfter = 24;

       oPara3.Range.InsertParagraphAfter();

 

       // Вставка таблицы 3 на 5, заполнение данными, и изменение первой строки: "жирный" и "курсив".

       Word.Table oTable;

       Word.Range wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       oTable = oDoc.Tables.Add(wrdRng, 3, 5); // 3 строки, 5 столбцов (Add требует 5 параметров, но мы записываем без двух последних параметров oMissing)

       oTable.Range.ParagraphFormat.SpaceAfter = 6;

       int r, c;

       string strText;

 

       for (r = 1; r <= 3; r++) // Заполняем строки

       {

 

           for (c = 1; c <= 5; c++) // Заполняем столбцы

           {

               strText = "r" + r + "c" + c;

               oTable.Cell(r, c).Range.Text = strText;

           }

           oTable.Rows[1].Range.Font.Bold = 1; // Меняем стиль первой строки: "жирный"

           oTable.Rows[1].Range.Font.Italic = 1; // Меняем стиль первой строки: "курсив"

       }

 

       // Вставка текста после таблицы

       Word.Paragraph oPara4;

       oRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       oPara4 = oDoc.Content.Paragraphs.Add(ref oRng);

       oPara4.Range.InsertParagraphBefore(); // Вставка отступ до с параметром 24 пт. (подтягиваем из oPara3 по умолчанию)

       oPara4.Range.Text = "Вставляем другую таблицу:";

       oPara4.Format.SpaceAfter = 24;

       oPara4.Range.InsertParagraphAfter(); // Вставка оступа после с параметром 24 пт.

 

       // Вставка таблицы 5 на 2, заполнение данными, и изменение размера ширины столбцов

       wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       oTable = oDoc.Tables.Add(wrdRng, 5, 2);

       oTable.Range.ParagraphFormat.SpaceAfter = 6;

 

       for (r = 1; r <= 5; r++)

       {

 

           for (c = 1; c <= 2; c++)

           {

               strText = "r" + r + "c" + c;

               oTable.Cell(r, c).Range.Text = strText;

           }

           oTable.Columns[1].Width = oWord.InchesToPoints(2); // Изменение ширины столбца 1

           oTable.Columns[2].Width = oWord.InchesToPoints(3); // Изменение ширины столбца 2

       }

 

       // Продолжаем вставку текста. Когда получим 7 дюймов от верхней части документа, вставим жёсткий разрыв страницы (иммитация нажатия Ctrl+Enter в документе)

       object oPos;

       double dPos = oWord.InchesToPoints(7);

       oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range.InsertParagraphAfter();

 

       do

       {

           wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

           wrdRng.ParagraphFormat.SpaceAfter = 6;

           wrdRng.InsertAfter("Текстовая строка");

           wrdRng.InsertParagraphAfter();

           oPos = wrdRng.get_Information(Word.WdInformation.wdVerticalPositionRelativeToPage); // Вставляем текст и получаем после каждой вставки информацию о положении на странице

       }

       while (dPos >= Convert.ToDouble(oPos));

       // Вставка разрыва страницы

       object oCollapseEnd = Word.WdCollapseDirection.wdCollapseEnd;

       object oPageBreak = Word.WdBreakType.wdPageBreak;

       wrdRng.Collapse(ref oCollapseEnd);

       wrdRng.InsertBreak(ref oPageBreak);

       wrdRng.Collapse(ref oCollapseEnd);

       B_Page_2.Enabled = true;

   }

 

Событие Click кнопки B _ Page _2 («Страница № 2»):

 

   private void B_Page_2_Click(object sender, EventArgs e)

   {

       Word.Range wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       wrdRng.InsertAfter("Текст на странице № 2. График:");

       wrdRng.InsertParagraphAfter();

 

       // Вставка диаграммы (одной из демонстрационных) из MSGraph

       Word.InlineShape oShape; // Поле под диаграмму

       object oClassType = "MSGraph.Chart.8"; // Тип диаграммы по умолчанию

       wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       oShape = wrdRng.InlineShapes.AddOLEObject(ref oClassType); // Вставка "пустой" (без парметров) диаграммы

 

       // oChart и oChartApp объекты: работа с объектами диаграмм через MSGraph

       object oChart;

       object oChartApp;

       oChart = oShape.OLEFormat.Object;

       oChartApp = oChart.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, oChart, null);

 

       // Изменение типа диаграммы (линии)

       object[] Parameters = new Object[1];

       Parameters[0] = 4; // xlLine = 4

       oChart.GetType().InvokeMember("ChartType", BindingFlags.SetProperty, null, oChart, Parameters);

 

       // Изменение рисунка диаграммы и выход из MSGraph

       oChartApp.GetType().InvokeMember("Update", BindingFlags.InvokeMethod, null, oChartApp, null);

       oChartApp.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, oChartApp, null);

       // После добавления диаграммы, её можно менять как полноценный объект диаграмм MSGraph

       // Отсюда, из документа, можно перейти из диаграммы в документе в Microsoft Graph и внести дополнительные изменения в диаграмме

 

       oShape.Width = oWord.InchesToPoints(6.25f); // Изменение ширины диаграммы

       oShape.Height = oWord.InchesToPoints(3.57f); // Изменение высоты диаграммы

 

       // Вставка текста без последующего отступа

       wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

       wrdRng.InsertParagraphAfter();

       wrdRng.InsertAfter("Конец.");

   }

 

Событие Click кнопки B _ Print («Печать»):

 

   private void B_Print_Click(object sender, EventArgs e)

   {

       Object time = 10000;

       oWord.Dialogs[Word.WdWordDialog.wdDialogFilePrint].Show(ref time);

   }

 

Многие действия в Word сопровождаются вызовом диалоговых окон (создание, открытие, сохранение и печать документа, изменение параметров шрифта, текста и прочее).

Допустим, необходимо предоставить пользователю возможность отправить документ на печать прямо из вашего приложения. Можно использовать функцию Document.PrintOut, но у неё «устрашающее» количество параметров, как и у большинства функций связи C# с COM объектами.

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

 

Dialogs — это коллекция диалоговых окон Word (всего более 238 элементов класса Microsoft.Office.Interop.Word.Dialog). Для того, что бы посмотреть все доступные диалоговые окна, кликните правой кнопкой мышки на WdWordDialog и выберите пункт меню Перейти к определению (F12):

 

Элементы доступны по своим именам и имеют понятные названия, например:

 

wdDialogFileNew — Новый документ;

wdDialogFileOpen — Открыть документ;

wdDialogFilePageSetup — Параметры страницы;

wdDialogFilePrint — Печать;

wdDialogFileSaveAs — Сохранить документ;

wdDialogFormatFont — Параметры шрифта.

 

Определение функции Dialog . Show в Microsoft . Office . Interop . Word . dll:

 

   [DispId(336)]

   int Show(ref object TimeOut = Type.Missing);

 

Параметр: «TimeOut» время в миллисекундах, через которое окно будет закрыто автоматически. Практика показывает, что некоторые виды окон игнорируют это время и сами не закрываются. Это относится к сохранению, открытию, созданию нового документа... Окна для указания параметров «печати, параметров страницы, шрифта....» закрываются по истечении указанного времени с нажатием «ОК» в этих окнах автоматически.

Значение, которое возвращает функция Show, зависит от вида окна и от того, как оно было закрыто. Если вышло время, или пользователь нажал «OK», или «Закрыть», то «-1», если «Отмена», то «0», если «По умолчанию», то «1». А вот если окно закрыто крестиком, то может быть «-1» или «-2», зависит от самого окна.

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

Заметим также, что при Object time = 0 диалоговое окно появляется на не установленное время, иначе, программа будет ожидать действий пользователя с диалоговым окном.

 

Событие Click кнопки B _ Scale («Масштаб»):

 

   private void B_Scale_Click(object sender, EventArgs e)

   {

       oWord.ActiveWindow.ActivePane.View.Zoom.Percentage = Convert.ToInt32(NUD_Scale.Value);

   }

 

Функция для нумерации страниц и событие Click кнопки B _ Number («Пронумеровать страницы»):

 

  // Метод пронумеровки страниц

   public void vInsertNumberPages(int viWhere, bool bPageFirst)

   {

       object alignment = Word.WdPageNumberAlignment.wdAlignPageNumberCenter;

       object bFirstPage = bPageFirst;

       object bF = true;

       // Создаём колонтитулы           

       oDoc.ActiveWindow.ActivePane.View.SeekView = Word.WdSeekView.wdSeekCurrentPageFooter; // Нижние колонтитулы страниц

 

       switch (viWhere)

       {

           case 1:

               alignment = Word.WdPageNumberAlignment.wdAlignPageNumberRight;

           break;

           case 2:

               alignment = Word.WdPageNumberAlignment.wdAlignPageNumberLeft;

           break;

       }

       oWord.Selection.HeaderFooter.PageNumbers.Add(ref alignment, ref bFirstPage);

   }

 

   private void B_Number_Click(object sender, EventArgs e)

   {

       vInsertNumberPages(1, true); // Цифра номера справа (1), с первой страницы (true); 0 – по центру

   }

 

Событие Click кнопки B _ Picture («Вставить рисунок»):

 

   private void B_Picture_Click(object sender, EventArgs e)

   {

       OFD_Picture.ShowDialog();

       oWord.Selection.InlineShapes.AddPicture(OFD_Picture.FileName, ref oMissing, ref oMissing, ref oMissing);

   }

 

Компилируем приложение (Debug) и запускаем. Нажимаем на «Открыть Word, ...», должно открыть окно Word (текущей версии, в данном случае Word 2010) с чистым документом. Активируется кнопка Страница № 1. Жмём. Видим следующее:

 

Рис. 3. 3. Окончательная работа первого блока: заполнение первой страницы документа Word (в Word 2010)

 

Затем жмём на кнопку Страница № 2 и наслаждаемся заполненным документом. На рисунках 3. 3 и 3. 4. Включено отображение знаков форматирования ( , в Word’е).

 

Рис. 3. 4. Окончательная работа первого блока: заполнение второй страницы документа Word (в Word 2010)

 

Рис. 3. 5. Окончательная работа первого блока: нумерация страниц, вставка рисунка (на позицию курсора!) и масштаб в 50% в Word (в Word 2010)

 

Проверяем работу других кнопок. Меняем масштаб отображения документа, вставляем нумерацию страниц и рисунок.

 

Небольшое замечание по поводу вставки изображения. Наш код вставляет изображение на место выделения (мигающий курсор в документе), что может быть весьма неудобным. Потому, следующий код метода Click для кнопки Вставить рисунок делает две операции: копирует изображение в буфер обмена и вставляет его в конец документа (не по выделению):

 

   private void B_Picture_Click(object sender, EventArgs e)

   {

       OFD_Picture.ShowDialog();

       // Вставит изображение на место выделения (если не перемещать выделение, то в начало документа)

       oWord.Selection.InlineShapes.AddPicture(OFD_Picture.FileName);

       Image newImage = Image.FromFile(OFD_Picture.FileName);

       Clipboard.SetImage(newImage);

       Word.Range wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

         // Вставит изображение из буфера обмена в конец документа

       wrdRng.Paste();

   }

 

Исполнение кода затирает буфер обмена! Можно прибегнуть к методу сохранения текущего буфера отдельно и восстановление после операции вставки изображения:

 

    private void B_Picture_Click(object sender, EventArgs e)

   {

 

       if (OFD_Picture.ShowDialog() == DialogResult.OK)

       {

           // Вставит изображение на место выделения (если не перемещать выделение, то в начало документа)

           oWord.Selection.InlineShapes.AddPicture(OFD_Picture.FileName);

           Image newImage = Image.FromFile(OFD_Picture.FileName);

           // Получаем данные из буфера обмена

           IDataObject iData;

           iData = Clipboard.GetDataObject();

           //MessageBox.Show(iData.GetData(DataFormats.Text).ToString());

           // Заносим туда изображение

           Clipboard.SetImage(newImage);

           Word.Range wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

           // Вставит изображение из буфера обмена в конец документа

           wrdRng.Paste();

           // Восстанавливаем буфер

           Clipboard.SetDataObject(iData);

       }

   }

 

Также код выше обезопасит приложение от ошибки, возникающей, в случае если пользователь не выбрал файла изображения в окне диалога.

 

Пример выполнения работы кода:

 

Рис. 3. 6. Окончательная работа первого блока: нумерация страниц, вставка рисунков в начало (на позицию курсора) и в конец документа и масштаб в 50% в Word (в Word 2010)

 


Дата добавления: 2019-09-13; просмотров: 751; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!