Программно убираем поля и колонтитулы в браузере Firefox под Windows

Зачем это нужно?


В нашей компании используется веб-приложение, одной из возможностей которого является печать заполненных форм. Начальство очень бесится, когда им приносят документы с колонтитулами браузера. Виноватым при этом делают веб-программиста — он же отвечает за веб-приложение.
Системные администраторы в курсе этого дела. Но зоопарк браузеров представлен несколькими видами особей. Хоть при установке их и убираются колонтитулы и поля, но зло не дремлет и черная магия делает свое дело — документы печатаются с колонтитулами и приходится снова убирать вручную. «До коль?» — спрашивает наш Отдел ИТ начальство.


Другие варианты решения описанной проблемы?


О, да! Перегонять документы в pdf и печатать их, так как их просмотрщики устанавливаются по умолчанию без колонтитулов. Мне как веб-программисту это и поручили. Я подозревал, что это решение дурное, но сказать себе это не попробовав я не посмел. Не знаю откуда у меня взялась такая привычка, но я не убеждаю заказчика, что его требование ему не нужно на самом деле, пока не буду уверен, что на это меня толкает не моя некомпетентность. Другими словами, не отказываюсь от задания, объясняя это отсутствием необходимости вместо присутствия своей лени. В общем, понеслось. mPDF, fpdf, tcpdf, dom_pdf. Первым попробовал mPDF — он справился с версткой точнее остальных без всяких плясок со стилями, но, к сожалению, не поддерживал скрипты для автопечати при открытии. Спас dom_pdf, добился полного соответствия и автопечати при открытии. Доказав себе, что моя лень при решении проблемы через pdf тут не при чем, я начал искать другие решения.

Ближе к делу!


Покопавшись в файлах Firefox, установленном на Windows XP, можно обнаружить файлик prefs.js. Быстрый поиск по содержимому показал наличие параметров очень похожие на искомые:

user_pref("print.printer_\\\\сеть-какая-то\\HP_Universal_Printing_PCL_5.print_footerleft", "");
user_pref("print.printer_\\\\сеть-какая-то\\HP_Universal_Printing_PCL_5.print_margin_right", "0");

Таких строк там несколько.

Ничего умнее я не придумал, как начать гуглить «cmd replace text» и тому подобное. Даже утилиты консольные нашел gsar, fart. Смысл жизни которых — в замене текста в файлах на нужный. Но появились две проблемы, которые я не смог решить: как передать строки, содержащие кавычки, и какую строку искать для замены.

Вот так я чуть-чуть заглянул в мир VBScript.

REM удаляет поля и колонтитулы в файле prefs.js настроек Firefox

' ProcessKillLocal.vbs
' Sample VBScript to kill a program
' Author Guy Thomas http://computerperformance.co.uk/
' Version 2.7 - December 2010
' ------------------------ -------------------------------'
Dim objWMIService, objProcess, colProcess
Dim strComputer, strProcessKill
strComputer = "."
strProcessKill = "'firefox.exe'"

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")

Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = " & strProcessKill )
For Each objProcess in colProcess
objProcess.Terminate()
Next
WSCript.Echo "Just killed process " & strProcessKill _
& " on " & strComputer

REM ----------------процесс завершен-------------------------

Const ForReading = 1    
Const ForWriting = 2

set re = New RegExp
re.IgnoreCase = true
re.Global = true
re.Multiline = true


REM Находим файл настроек. Путь к нему указан в специальном файле в APPDATA
Set objFSO = CreateObject("Scripting.FileSystemObject")

Set oShell = CreateObject( "WScript.Shell" )
appdir=oShell.ExpandEnvironmentStrings("%APPDATA%")

Set objFile = objFSO.OpenTextFile(appdir & "\Mozilla\Firefox\profiles.ini", ForReading)
profile_str = objFile.ReadAll
objFile.Close


re.Pattern = "(Profiles/.+\w)$"
Set mt = re.Execute(profile_str)
profile_path = mt(0).Value

ReDim PrefsFile(4)
PrefsFile(0) = appdir
PrefsFile(1) = "\Mozilla\Firefox\"
PrefsFile(2) = profile_path
PrefsFile(3) = "\prefs.js"

strFileName = Join(PrefsFile, "")

Set objFile = objFSO.OpenTextFile(strFileName, ForReading)
strText = objFile.ReadAll
objFile.Close

REM "(\.print_margin_bottom"", "")(.+)(""\);)$" - поиск .print_margin_bottom", "0");

Dim SearchPtStr(6)

SearchPtStr(0) = "print_footercenter"
SearchPtStr(1) = "print_footerleft"
SearchPtStr(2) = "print_footerright"
SearchPtStr(3) = "print_headercenter"
SearchPtStr(4) = "print_headerleft"
SearchPtStr(5) = "print_headerright"

For Each str In SearchPtStr
    re.Pattern = "(\." & str & """, "")(.+)(""\);)$"
    Set myMatches = re.Execute(strText)
    For Each myMatch in myMatches
       If Len(myMatch.Value)>1 Then
        strText = re.Replace(strText, "$1$3")
       End if
    Next
Next

Dim SearchPtInt(4)
SearchPtInt(0) = "print_margin_bottom"
SearchPtInt(1) = "print_margin_left"
SearchPtInt(2) = "print_margin_right"
SearchPtInt(3) = "print_margin_top"

For Each str In SearchPtInt
    re.Pattern = "(\." & str & """, "")(.+)(""\);)$"
    Set myMatches = re.Execute(strText)
     For Each myMatch in myMatches
        If Len(myMatch.Value)>1 Then
           strText = re.Replace(strText, "$10$3")
        End if
     Next
Next

Set objFile = objFSO.OpenTextFile(strFileName, ForWriting)
objFile.WriteLine strText
objFile.Close



В первой части скрипта мы завершаем процесс firefox.exe, так как при выходе он перезаписывает prefs.js. Фрагмент кода для этого был нагуглен и скопирован почти без изменений.
В следующей части скрипта мы читаем файл Application Data\Mozilla\Firefox\profiles.ini,
в котором хранится путь профиля, сохраняем в profile_path. Затем, по этому пути мы загружаем содержимое файла настроек в переменную strText. Далее, с помощью цикла и регулярного выражения
"(\." & str & """, "")(.+)(""\);)$"
мы находим строки, похожие на
".print_margin_bottom", «0»);"


(таких строк в файле настроек может быть много, в зависимости от количества принтеров). Найденные вхождения мы заменяем на $1$3 для строковых параметров (колонтитулов) и $10$3 для числовых параметров. Т.е. делаем либо пустые кавычки, либо 0 в кавычках.
строку после замены мы помещаем обратно в файл.

В программе есть странное место:
If Len(myMatch.Value)>1 Then
strText = re.Replace(strText, "$1$3")
End if

При re.Global = true и таком регулярном выражении попадаются пустые соответствия, замена которых превращает файл настроек в кровавое месево. Условие добавлено, чтобы это исключить. Я подозреваю, что ошибка в регулярном выражении, но самостоятельно решить этот вопрос не смог.

Скрипт обозвать, например, rem_headers_ff.vbs и можно запускать из командной строки
cscript rem_headers_ff.vbs


Как же это решает изначальную проблему?


Настройки колонтитулов IE хранятся в реестре, что программно несложно изменять.
Настройки FF мы научились перезаписывать.
Chrome кроме меня почему-то никто больше у нас не использует.
Остался один маленький шажок — решить проблему для Opera.
Поделиться публикацией

Комментарии 7

    +6
    Ну не знаю, все же зря от пдф-а отказались.
    Такие костыли как-то совсем некрасиво выглядят.
    Да, кстати, если отчет сверстан нормально, то его можно сохранить как html (только текст), и он будет отлично открываться всякими вордами-экселями. Оттуда уже можно и печатать как нравится, и пересылать — в общем красота. Понятно, что его надо специально подготовить (важные стили включить в head, повыкидывать лишние блоки если они есть и создавать их динамически).
      0
      А еще нужно научить пользователей сохранять html-страницы. Ладно, pdf добавляло несколько кликов при первой печати и увеличивало время (время тратится на открытие reader'a), а компьютеры не топовые. Но вот сохранение html в другой формат вручную и затем опять же вручную его печатать — это заняло бы топовые места извращения на парой сотней пользователей.
      Это не совсем костыли, учитывая, что это все можно подогнать под групповую политику — так вообще красота.
        0
        Повторюсь, правильный (с точки зрения ms office) html хорош именно тем, что позволяет обращаться с отчетом в привычном ворде/экселе (а не каком-то там браузере или ридере). Сами знаете уровень офисного планктона, они же даже письма предпочитают писать в ворде и отправлять потом вложением по этому вашему емейлу.
          0
          Так в том то и дело, что это не отчет. Это заявка, и все, что от нее нужно пользователю — это распечатать ее.
      +1
      У нас ситуация с точностью наоборот — хотите чтобы все работало, пользуетесь хромом. И ниипет. Само приложение устанавивается как ярлык приложения хрома.
        0
        Идея ситуация, но бывают тупорылые стандарты в компаниях ИЕ и не ИЕТ!
        Если хотя бы лиса стоит, уже прогресс.
          0
          Каким то магическим образом вместо слово Хорошая, попало слово Идея. Спать похоже пора

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое