VBScript. Быстрое конвертирование docx в pdf с заполнением мета свойств документов

Github Latest docxToPdf Github LICENSE docxToPdf Github Repo Github Commit docxToPdf

Во время дистанционного обучения моей школы, где я работаю IT Администратором, я столкнулся с одной проблемой. Очень много времени уходит на конвертации документов MS Word в формат Adobe PDF. А ведь сегодня дистанционное обучение не закончено и мне вновь придётся это делать. А это двадцать файлов только по основному расписанию за один день. А в неделе – пять учебных дней. Итого сто файлов и это не считая расписаний внеурочной деятельности. А также красочных недельных расписаний. И всё это "нужно сделать вчера".

На что же именно уходило много времени?

Первое – это проверить все ссылки. От этого никуда не деться и это проходит в ручном режиме. Все ссылки должны вести не на результаты поиска, а на конкретный источник. Поисковая система не может считаться площадкой прохождения уроков. Я не буду вдаваться в SEO подробности, но у каждого пользователя могут отличаться результаты в поисковой выдаче. А если произошла в течении дня-двух переранжировка поисковыми ботами? И т. д. и т. п. А так же в поисковой выдаче может оказаться нежелательная реклама.

Второе – заполнение мета тегов документа PDF после его конвертирования. Ведь согласитесь, что на много удобнее и приятнее видеть в браузере название документа, а не имя файла. А со стороны SEO так это вообще золотое правило. Поэтому лично я отношусь очень серьёзно к мета тегам любых документов, которые впоследствии выкладываются в общий доступ.

А родители могут просматривать не один документ, а два, три, четыре... (сколько там детей в семье?)

VBScript. Быстрое конвертирование docx в pdf с заполнением мета свойств документов

Так же много времени уходит даже на обычные клики, наведение и т. д. уже на конвертирование файлов.

И так. Первое и второе можно выполнить непосредственно в MS Word. Или второй пункт можно выполнить в Adobe Acrobat DC.

Как известно программист человек ленивый и он будет искать самый короткий путь выполнения задачи. К чему я и пришёл.

Я написал VBScript, который пробегает по файлам docx в папке, заполняя все нужные свойства документа, сохраняя далее в PDF формат.

У меня выработана определённая структура папок и файлов. Основные папки – rs (Расписания уроков), vd – (Внеурочная деятельность). В каждой из этих папок далее идут папки по дням в формате dd.mm.YYYY. Имена файлов – здесь всё просто. 1«А».docx, 1«Б».docx ….. и т. д. по классам.

VBScript. Быстрое конвертирование docx в pdf с заполнением мета свойств документов

В чём же идея. День, месяц, год – берём из имени папки, класс берём из имени файла. Генерируем заголовок, записываем свойства, транслит имени 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

Поделиться