VBScript. Быстрое конвертирование docx в pdf с заполнением мета свойств документов
Во время дистанционного обучения моей школы, где я работаю IT Администратором, я столкнулся с одной проблемой. Очень много времени уходит на конвертации документов MS Word в формат Adobe PDF. А ведь сегодня дистанционное обучение не закончено и мне вновь придётся это делать. А это двадцать файлов только по основному расписанию за один день. А в неделе – пять учебных дней. Итого сто файлов и это не считая расписаний внеурочной деятельности. А также красочных недельных расписаний. И всё это "нужно сделать вчера".
На что же именно уходило много времени?
Первое – это проверить все ссылки. От этого никуда не деться и это проходит в ручном режиме. Все ссылки должны вести не на результаты поиска, а на конкретный источник. Поисковая система не может считаться площадкой прохождения уроков. Я не буду вдаваться в SEO подробности, но у каждого пользователя могут отличаться результаты в поисковой выдаче. А если произошла в течении дня-двух переранжировка поисковыми ботами? И т. д. и т. п. А так же в поисковой выдаче может оказаться нежелательная реклама.
Второе – заполнение мета тегов документа PDF после его конвертирования. Ведь согласитесь, что на много удобнее и приятнее видеть в браузере название документа, а не имя файла. А со стороны SEO так это вообще золотое правило. Поэтому лично я отношусь очень серьёзно к мета тегам любых документов, которые впоследствии выкладываются в общий доступ.
А родители могут просматривать не один документ, а два, три, четыре... (сколько там детей в семье?)
Так же много времени уходит даже на обычные клики, наведение и т. д. уже на конвертирование файлов.
И так. Первое и второе можно выполнить непосредственно в MS Word. Или второй пункт можно выполнить в Adobe Acrobat DC.
Как известно программист человек ленивый и он будет искать самый короткий путь выполнения задачи. К чему я и пришёл.
Я написал VBScript, который пробегает по файлам docx в папке, заполняя все нужные свойства документа, сохраняя далее в PDF формат.
У меня выработана определённая структура папок и файлов. Основные папки – rs (Расписания уроков), vd – (Внеурочная деятельность). В каждой из этих папок далее идут папки по дням в формате dd.mm.YYYY. Имена файлов – здесь всё просто. 1«А».docx, 1«Б».docx ….. и т. д. по классам.
В чём же идея. День, месяц, год – берём из имени папки, класс берём из имени файла. Генерируем заголовок, записываем свойства, транслит имени PDF файла для размещения на сервере, сохраняем PDF файл. Плюсом – я генерирую CSV файл, где записываю Заголовок и реальный путь к файлу, где он будет находиться на сервере. На сервере у нас тоже очень строгий порядок с деревом директорий. Этот порядок живёт строго по моим законам. Да и к тому же, в CMS сайта (Evolution CMS), для вывода документов мы используем MultiTV, в котором для его заполнения будем использовать как раз тот самый CSV файл.
В скрипте мы только изменяем начало заголовка документа (Расписание занятий или Расписание занятий внеурочной деятельности) и субдиректорию, если вам нужен CSV файл, перетаскиваем папку с соответствующими файлами на скрипт vbs.
И да, очень важный момент, файлы должны быть разблокированиы и неоткрытыми ни в одном приложении.
Как разблокировать файлы я описывал здесь - Разблокировка файлов скаченных с Интернета.
Ну и код самого скрипта:
Option Explicit
Const PDF = 17
Const fTitle = "РАСПИСАНИЕ ЗАНЯТИЙ "
Const cTitle = " КЛАССА НА "
Const tGboy = "ГБОУ СОШ п. Комсомольский м. р. Кинельский Самарской обл."
Const assetsFolder = "assets/files/0000/do/"
Const assetsType = "/rs/"
Dim docTitle
Dim objWord
Dim objDocument
Dim strSourceFolder
Dim objFSO
Dim objFile
Dim customProp
Dim prop
Dim fCount
Dim csvFile
Dim csvText
Dim rsDate
' Функция транслита
Function Rus2Lat(strRus)
Dim i
Dim strTemp
Dim strLat
For i = 1 To Len(strRus)
strTemp = Mid(strRus, i, 1)
Select Case strTemp
Case "а"
strLat = strLat & "a"
Case "А"
strLat = strLat & "a"
Case "б"
strLat = strLat & "b"
Case "Б"
strLat = strLat & "b"
Case "в"
strLat = strLat & "v"
Case "В"
strLat = strLat & "v"
Case "г"
strLat = strLat & "g"
Case "Г"
strLat = strLat & "g"
Case "д"
strLat = strLat & "d"
Case "Д"
strLat = strLat & "d"
Case "е"
strLat = strLat & "e"
Case "Е"
strLat = strLat & "e"
Case "ё"
strLat = strLat & "e"
Case "Ё"
strLat = strLat & "e"
Case "ж"
strLat = strLat & "zh"
Case "Ж"
strLat = strLat & "zh"
Case "з"
strLat = strLat & "z"
Case "З"
strLat = strLat & "z"
Case "и"
strLat = strLat & "i"
Case "И"
strLat = strLat & "i"
Case "й"
strLat = strLat & "i"
Case "Й"
strLat = strLat & "i"
Case "к"
strLat = strLat & "k"
Case "К"
strLat = strLat & "k"
Case "л"
strLat = strLat & "l"
Case "Л"
strLat = strLat & "l"
Case "м"
strLat = strLat & "m"
Case "М"
strLat = strLat & "m"
Case "н"
strLat = strLat & "n"
Case "Н"
strLat = strLat & "n"
Case "о"
strLat = strLat & "o"
Case "О"
strLat = strLat & "o"
Case "п"
strLat = strLat & "p"
Case "П"
strLat = strLat & "p"
Case "р"
strLat = strLat & "r"
Case "Р"
strLat = strLat & "r"
Case "с"
strLat = strLat & "s"
Case "С"
strLat = strLat & "s"
Case "т"
strLat = strLat & "t"
Case "Т"
strLat = strLat & "t"
Case "у"
strLat = strLat & "u"
Case "У"
strLat = strLat & "u"
Case "ф"
strLat = strLat & "f"
Case "Ф"
strLat = strLat & "f"
Case "х"
strLat = strLat & "kh"
Case "Х"
strLat = strLat & "kh"
Case "ц"
strLat = strLat & "ts"
Case "Ц"
strLat = strLat & "ts"
Case "ч"
strLat = strLat & "ch"
Case "Ч"
strLat = strLat & "ch"
Case "ш"
strLat = strLat & "sh"
Case "Ш"
strLat = strLat & "sh"
Case "щ"
strLat = strLat & "sch"
Case "Щ"
strLat = strLat & "sch"
Case "ъ"
strLat = strLat & ""
Case "Ъ"
strLat = strLat & ""
Case "ы"
strLat = strLat & "y"
Case "Ы"
strLat = strLat & "y"
Case "ь"
strLat = strLat & ""
Case "Ь"
strLat = strLat & ""
Case "э"
strLat = strLat & "e"
Case "Э"
strLat = strLat & "e"
Case "ю"
strLat = strLat & "yu"
Case "Ю"
strLat = strLat & "yu"
Case "я"
strLat = strLat & "ya"
Case "Я"
strLat = strLat & "ya"
case "«"
strLat = strLat & ""
case "»"
strLat = strLat & ""
case " "
strLat = strLat & "-"
Case Else
strLat = strLat & strTemp
End Select
Next
Rus2Lat = strLat
End Function
' Если у скрипта есть аргументы
If WScript.Arguments.Count = 1 Then
rsDate = ""
' Первый аргумент должен быть папкой, которую будем обрабатывать.
strSourceFolder = WScript.Arguments.Item(0)
' Создаём объект для работы с файловой системой
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
' Если папка существует
If objFSO.FolderExists(strSourceFolder) Then
Set objWord = Nothing
fCount = 0
Set csvFile = objFSO.CreateTextFile(strSourceFolder & "\csv.csv", True)
For Each objFile In objFSO.GetFolder(strSourceFolder).Files
If StrComp(objFSO.GetExtensionName(objFile.Name), "docx", vbTextCompare) = 0 Then
' Запускаем Word если он ещё не запущен
If objWord Is Nothing Then
Set objWord = WScript.CreateObject("Word.Application")
End If
' Пустой заголовок
docTitle = ""
' Открываем документ
Set objDocument = objWord.Documents.Open(objFile.Path)
' Получаем объект свойст документа
Set customProp = objDocument.BuiltinDocumentProperties
' Получаем дату
rsDate = objFSO.GetBaseName(strSourceFolder) & "." & objFSO.GetExtensionName(strSourceFolder)
' Собираем заголовок
docTitle = fTitle & objFSO.GetBaseName(objFile.Name) & cTitle & rsDate
' Перебираем свойства документа
For Each prop in customProp
' Устанавливаем нужные свойства документа
Select case prop.Name
' Заголовок документа
case "Title"
prop.Value = docTitle & " " & tGboy
' Тема документа
case "Subject"
prop.Value = docTitle & " " & tGboy
' Автор документа
case "Author"
prop.Value = tGboy
' Компания
case "Company"
prop.Value = tGboy
End Select
Next
' Сохраняем документ как PDF. Транслит имени файла для сохранения
' Так же сначало сохраниться сам документ перед конвертацией.
objDocument.SaveAs2 objFSO.BuildPath(objFile.ParentFolder.Path, Rus2Lat(objFSO.GetBaseName(objFile.Name)) & ".pdf"), PDF
' Записываем данные в csv файл
csvText = """" & docTitle & """;""" & assetsFolder & rsDate & assetsType & Rus2Lat(objFSO.GetBaseName(objFile.Name)) & ".pdf"""
csvFile.WriteLine(csvText)
' Закрываем документ
objDocument.Close
' Обнуляем переменную
' Set objDocument = Nothing
fCount = fCount + 1
End If
Next
' Если Word запущен - закроем его
If Not objWord Is Nothing Then
objWord.Quit
End If
' Обнуляем переменную
Set objWord = Nothing
' Закрываем csv файл
csvFile.Close
' Вывод сообщения о количестве обработанных файлов
MsgBox "Обработано " & fCount & " файлов"
End If
' Обнуляем переменную
Set objFSO = Nothing
Else
MsgBox "Not found parametrs"
End If
' Выходим из выполнения сценария.
WScript.Quit 0
Основной источник документации по работе с MS Word
Посмотреть репозиторий на GitHub