Додавання водяного знака і колонтитула в документ. Варіант вирішення завдання

  1. Корисні матеріали по темі
  2. опис процесу
  3. Реалізація
  4. Труднощі, що виникли при реалізації, і варіанти їх вирішення.
  5. результати

На проекті одним із завдань було завдання по автоматичному формуванню і зняття підкладок (водяних знаків) і додаванню колонтитулів в документ.
У статті розглядається варіант рішення - програмна реалізація такого завдання.

Корисні матеріали по темі

Вставка зображення в документ Word - як додавати водяний знак у документ Word

Вставка зображення в документ Excel - в документ Excel

Два способи вставити зображення (штрихкод) в документ Word.Application - як додавати зображення в колонтитул

Кілька способів форматування і обробки даних в Word документах за допомогою IS-Builder - корисності при програмній роботі з документами в Word

опис процесу

У компанії N є певного виду документи, які можуть перебувати в 3 умовно названих стадіях: «Розробка», «Чинний», «Застарілий» (ці 3 умовно названі стадії жодним чином можуть не залежати і не відображати стадії ЖЦ документа і / або стан версій документа в системі).

Кожна стадія характеризується наступними параметрами:

1. Якщо документ в стадії «Розробка», то у документа повинна бути в тілі підкладка (водяний знак) з певним текстом, наприклад, «Розробка».

Додатково в нижньому колонтитулі документа повинна була з'явитися рядок: «ДОВІДКОВО. Вивантажено з DIRECTUM ». Тут потрібно додати, що при експорті документа на диск функціональність по показу поточних дати і часу повинна зберегтися. Тобто експортувала я документ вчора, відкрила сьогодні о 17:10, то і в документі повинно відбитися 17:10.

Документи можуть бути в форматі .doc, .docx, .rtf.

Ну і звичайно не має значення, відкрила я документ на читання або редагування, дата і час повинні оновлюватися.

Виглядати має це приблизно так:

2. Якщо документ в стадії «Чинний», то підкладка з документа повинна піти, колонтитул повинен залишитися на місці.

3. Якщо документ в стадії «Застарілий», то в документ знову повинен додатися водяний знак, але тепер з текстом «Застарілий».

Стадії документа можуть змінюватися тільки в порядку: Розробка → Чинний → Застарілий. Зміна стадії на значення «Чинний» відбувається при реєстрації наказу по введенню в дію такого документа, а в стадію «Застарілий» документ переходить при актуалізації / переробці документа (при актуалізації / переробці створюється новий документ, а не версія цього ж документа), і знову ж, тільки при реєстрації наказу.

Реалізація

Для початку розділимо завдання на частини:

1. По-перше. Як додати водяний знак у документ?

Є відразу 2 способи:

  • Нагугліть.
  • Записати макрос при вставці водяного знака і переписати отриманий код на ISBL.

Дотримуючись будь-якого із способів, в результаті отримаємо приблизно такий код:

... PRESENT_TEXT_EFFECT = 0 // Текстовий ефект, значення збігаються формам, перерахованим в діалоговому вікні WordArt Gallery FONT_NAME = "Times New Roman" // Найменування шрифту FONT_SIZE = 122 // Розмір шрифту FONT_BOLD = FALSE // Використовувати жирний шрифт FONT_ITALIC = FALSE // використовувати курсив LEFT_POINTS = 1 // Положення написи від лівого краю TOP_POINTS = 1 // Положення написи від верхнього краю Text = 'Текст водяного знака' ... WordArt = Selection.HeaderFooter.Shapes.AddTextEffect (PRESENT_TEXT_EFFECT; Text; FONT_NAME; FONT_SIZE; FONT_BOLD; FONT_ITALIC; LEFT_POINTS; TOP_POINTS) WordArt.Select WordArt.TextEffect.NormalizedHeight = FALSE WordArt.Fill.Visible = TRUE WordArt.Fill.Solid WordArt.Fill.ForeColor.RGB = 255 // колір - червоний WordArt.Fill.Transparency = 0.5 // напівпрозорість WordArt.Rotation = 315 // поворот в градусах WordArt.Line.Visible = FALSE WordArt.LockAspectRatio = FALSE WordArt.ZOrder (5) // За текстом ...

2. По-друге. В який момент додавати рядок в нижній колонтитул таким чином, щоб в документі відбивалися поточні дата і час?

Виходячи з вимог, найдоступніший і простий спосіб, це додавати елемент управління «Поле» з заданими властивостями:

... FONT_SIZE = 5 wdLine = 5 TEXT = "ДОВІДКОВО. Вивантажено з DIRECTUM:" wdColor = -671055617 // BLUE https://msdn.microsoft.com/en-us/library/bb237561(v=office.12).aspx -671055617 Font.Color = -671 055 617 ... Field = Footer.Range.Fields.Add (FooterRange; -1; 'DATE \ @ "dd.MM.yyyy H: mm: ss"'; True) FooterRange.SetRange (0; 69) FooterRange.Font.Color = wdColor // Blue FooterRange.Font.Size = FONT_SIZE FooterRange.InsertBefore (TEXT) Selection.EndKey (wdLine) ...

І так, невеликі заготовки коду є, йдемо далі.

3. Первісне поява документа. За бізнес-процесу такі документи можуть бути створені як з шаблону, так і з файлу.

Як тільки такий документ з'являється в системі, то у нього в тілі повинен бути водяний знак, відповідний стадії «Розробка».

Якщо з шаблоном все зрозуміло - просто налаштовуємо в потрібному форматі шаблон для певного виду документа, то зі створенням з файлу доведеться помучитися.

Йдемо від обмежень: тому що на занесення документа ми вплинути не можемо, то додавати водяний знак і потрібний колонтитул будемо після створення документа в системі.

Додатково враховуємо, що для додавання водяного знака потрібно експортувати документ → додати в нього знак і підкладку → зберегти → імпортувати в ту ж версію.

Разом: в подію даного типу картки Збереження Після для документів з розширенням (.doc, .docx, .rtf), створеним з файлу, стартуємо завдання, в рамках якої буде відбуватися додавання підкладки в документ.

Очевидний мінус такого рішення - необхідні водяний знак і колонтитул може з'явитися набагато пізніше створення документа при наявності слабкої сервера зі службою WF.

4. Оскільки стадії документа можуть проходити строго послідовно, а в рамках бізнес-процесу стадія документа змінюється тільки в типовому маршруті при певних умовах (при реєстрації наказу), то з видаленням водяного знака при зміні стадії документа на «Діє» і додаванням водяного знака в разі зміни стадії документа на «Застарілий» проблем бути не повинно - виконуємо дані дії на сервері, де встановлена служба WF, в рамках все того ж типового маршруту по реєстрації наказу.

Труднощі, що виникли при реалізації, і варіанти їх вирішення.

1. Перша проблема, яка виникла, це власне вставка водяного знака в документі посередині.

Здавалося б, варіантів відразу є два:

  • Використовувати константи MS Word для розташування тексту посередині
  • Або використовувати невигадливі формули для обчислення середини листа

Перший спосіб вимагає зусиль, потрібно «нагугліть» потрібні змінні, а математику ніби й так знаємо. Тому, пишемо код!

Тут виникла проблема наступного характеру.

При вставці тексту методом .AddTextEffect () потрібно задати координати майбутньої фігури. Потім, якщо місце розташування фігури на сторінці аркуша не подобається, фігуру можна розташувати в іншому місці методами .Left і .Top. Але на деяких документах результат міг бути непередбачуваний: текст міг розташовуватися як десь зовсім зліва, що ледь з'являється текст «... водяного знака», так і десь далеко праворуч, і результатом була підкладка «Текст у ...».

Така картина зовсім не радувала. Тому необхідно було визначити, чому так відбувається.

Для цього треба було:

1) Записати макрос при вставці водяного знака в документ, де текст знака розташовувався не посередині. Результат був такий же, як і при додаванні водяного знака в документ, в якому водяний знак розташовувався як потрібно:

... Selection.ShapeRange.RelativeHorizontalPosition = _ wdRelativeVerticalPositionMargin Selection.ShapeRange.RelativeVerticalPosition = _ wdRelativeVerticalPositionMargin Selection.ShapeRange.Left = wdShapeCenter Selection.ShapeRange.Top = wdShapeCenter ...

2) Ну що ж, треба дізнатися значення констант (залишу корисну посилання на значення констант тут https://msdn.microsoft.com/en-us/library/office/aa211923(v=office.11).aspx

Начебто все добре, підставляй та запускай.

2.Здесь виникла інша проблема, про яку згадується тільки тоді, коли вона зустрічається: обмежена можливість передачі даних певного типу (наприклад, «single») в ISBL.

Вирішилося все досить просто - шматок функції переписався на VBS:

... PRESENT_TEXT_EFFECT = 0 // Текстовий ефект, значення збігаються формам, перерахованим в діалоговому вікні WordArt Gallery FONT_NAME = "Times New Roman" // Найменування шрифту FONT_SIZE = 122 // Розмір шрифту FONT_BOLD = FALSE // Використовувати жирний шрифт FONT_ITALIC = FALSE // використовувати курсив LEFT_POINTS = 1 // Положення написи від лівого краю TOP_POINTS = 1 // Положення написи від верхнього краю Text = 'Текст водяного знака' wdRelativeHorizontalPositionPage = 1 // значення однойменної константи в MS Word wdRelativeVerticalPositionPage = 1 // значення однойменної константи в MS Word wdRelativeHorizontalSizePage = 1 // значення однойменної константи в MS Word wdRelativeVerticalSizePage = 1 // значення однойменної константи в MS Word wdShapeCenter = -999995 // значення однойменної константи в MS Word wdShapePositionRelativeNone = -999999 // значення однойменної константи в MS Word wdShapeSizeRelativeNone = -999999 // значення однойменної константи в MS Word ... ScriptControl = CreateObject ( "MSScriptControl.ScriptControl") ScriptControl.Language = "VBScript" ScriptControl.Reset ScriptControl.AddObject ( "DocApplication"; DocApplication) ScriptText = Format ( 'Function Insert () Set Selection = DocApplication.Selection Set WordArt = Selection.HeaderFooter.Shapes.AddTextEffect (% 0: s, "% 1: s", "% 2: s",% 3: s,% 4: s,% 5: s, 0, 0) WordArt.Select WordArt.TextEffect.NormalizedHeight = FALSE WordArt.Fill.Visible = TRUE WordArt.Fill.Solid WordArt.Fill.ForeColor.RGB = RGB (255, 0, 0) WordArt.Fill.Transparency = 0.5 WordArt.Rotation = 315 WordArt.Line.Visible = FALSE WordArt.LockAspectRatio = FALSE WordArt.ZOrder (5) WordArt.RelativeHorizontalPosition =% 6: s WordArt.RelativeVerticalPosition =% 7: s WordArt.RelativeHorizontalSize =% 8: s WordArt.RelativeVerticalSize =% 9: s WordArt.Left =% 10: s WordArt.LeftRelative =% 11: s WordArt.Top =% 10: s WordArt.TopRelative =% 11: s WordArt. WidthRelative =% 12: s WordArt.HeightRelative =% 12: s End Function '; ArrayOf (PRESENT_TEXT_EFFECT; Text; FONT_NAME; FONT_SIZE; FONT_BOLD; FONT_ITALIC; wdRelativeHorizontalPositionPage; wdRelativeVerticalPositionPage; wdRelativeHorizontalSizePage; wdRelat iveVerticalSizePage; wdShapeCenter; wdShapePositionRelativeNone; wdShapeSizeRelativeNone)) ScriptControl.AddCode (ScriptText) ScriptControl.Run ( "Insert") ...

Але, на жаль, первісну проблему по розташуванню тексту посередині повністю вирішити таким способом не вдалося.

3. Методом ретельного порівняння документів було встановлено наступне: що водяний знак додається не посередині документа в разі, якщо в верхньому колонтитулі документа є таблиця. І вище цієї таблиці немає порожнього рядка.

В результаті була додана і обробка таких ситуацій:

wdSeekCurrentPageHeader = 9 wdStory = 6 wdWithInTable = 12 wdCollapseStart = 1 wdSeekMainDocument = 0 ... ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader Selection.HomeKey (wdStory) if Selection.Information (wdWithInTable) = True Selection.SplitTable endif HeaderRange.Collapse (wdCollapseStart) ScriptText = Format ( 'Function Insert () ... ... ... ScriptControl.Run ( "Insert") ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument ...

PS: і до речі, доданий таким способом водяний знак видалити вручну (тобто через стандартний пункт меню MS Word 2010 Підкладка - Видалити підкладку) не виходить.

4. Наступна проблема була пов'язана з додаванням рядка «ДОВІДКОВО. Вивантажено з DIRECTUM »в нижній колонтитул документа способом, представленим вище.

Полягала вона в тому, що в документах, що створюються з файлу вже міг бути свій колонтитул, і додавання потрібного нам колонтитула вищевказаним способом призводило до того, що весь нижній колонтитул віддалявся.

Як підсумок, код був переписаний наступним чином (замість .Range.Fields.Add () використовувати метод .InsertDateTime ()):

... wdColor = -671055617 // BLUE https://msdn.microsoft.com/en-us/library/bb237561(v=office.12).aspx wdStory = 6 wdLine = 5 wdCalendarWestern = 0 TEXT = "ДОВІДКОВО. Вивантажено з DIRECTUM: "wdExtend = 1 FONT_SIZE = 5 ... Selection.EndKey (wdStory) Selection.InsertDateTime ( 'dd.MM.yyyy H: mm: ss'; TRUE; 0; wdCalendarWestern; FALSE) Selection.HomeKey (wdLine) Selection.TypeText (TEXT) Selection.EndKey (wdLine) // Виділити кольором Selection.HomeKey (wdLine; wdExtend) Selection.Font.Name = 'Arial' Selection.Font.Color = wdColor // Blue Selection.Font.Size = FONT_SIZE ...

результати

В результаті був реалізований механізм з автоматичного формування і зняття підкладок (водяних знаків) і формуванню колонтитулів в документі.

При цьому всі маніпуляції з тілом документа відбуваються в прихованому для користувача режимі.

Як додати водяний знак у документ?
В який момент додавати рядок в нижній колонтитул таким чином, щоб в документі відбивалися поточні дата і час?