Автоматизация пережатия pdf файлов

Задача: есть некоя файловая помойка, размер которой вырос до неприличных размеров. Необходимо pdf файлы пережать до «еле читабельного» состояния.

Решение: напишем соответствующий скрипт на Bash

#! /bin/bash
from='2025-01-15'
to='2025-01-17'

find ~/wedwewe -type f -newermt "$from" ! -newermt "$to" -name "*.pdf" | while read fname; do
  echo "-compress: $fname"
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=res.pdf "$fname"
  if [ $? -eq 0 ]; then
    echo OK
    mv res.pdf "$fname"
  else
    echo FAIL
  fi
done

Что делает этот скрипт? А просто ищет все файлы созданные в указанном диапазоне дат. Далее последовательно пытается пережать каждый файл, и если это происходит успешно, то заменяет оригинал на получившийся пережатый файл. Опции dPDFSETTINGS:

/screen Более низкое качество и меньший размер. (72 т/д)
/ebook Лучшее качество, но чуть больший размер (150 dpi)
/prepress Вывод имеет более высокий размер и качество (300 dpi)
/printer Качество вывода подходит для принтерной печати (300 dpi)
/default Выбирает вывод, который подходит для нескольких целей, однако может создавать большие PDF-файлы.

Update: со временем скрипт чуть изменился. А именно добавил проверку «а помогло ли сжатие». Если эффекта нет, то и не заменяем пережатый файл

#! /bin/bash
from='2025-01-13'
to='2025-01-17'

find ~/shwedwed -type f -newermt "$from" ! -newermt "$to" -name "*.pdf" | while read fname; do
  echo "-compress: $fname"
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dNOPAUSE -dQUIET -dBATCH -sOutputFile=res.pdf "$fname"
  if [ $? -eq 0 ]; then
    echo OK
    size_before=$(wc -c <"$fname")
    size_after=$(wc -c <"res.pdf")
    if [[ $size_before -gt $size_after ]]
	then 
	    echo "-результат сжатия хороший. Заменяем файл..."
	    mv res.pdf "$fname"
	else 
	    echo "-сжатие не удачное, пропускаем.."
    fi
  else
    echo FAIL
  fi
done

WordPress: просмотр pdf с параметром FitH

В WordPress есть возможность разместить на странице pdf файл в контейнере object, при помощи стандартного блока «Файл». Но есть нюанс — из настраиваемых параметров размера — только высота в пикселях. Ширина автоматически при просмотре подразумевается 100%.. Соответственно файл встраивается в страницу с автоматическим параметром отображения (т.е. не на всю ширину страницы). Для того чтобы страница растянулась на всю ширину экрана, нужно добавить параметр view, например чтобы было примерно так:

<object data-wp-bind--hidden="!state.hasPdfPreview" class="wp-block-file__embed" data="Полезные_советы.pdf#view=FitH" type="application/pdf" style="width:100%;height:800px"></object>

Но, к сожалению после редактирования html кода блока, он ломается. Поэтому одним из решений является написание плагина, который ищет на страницах размещенный pdf файл, и добавляет ему соответствующий параметр. Вот как это реализовано у меня:

Добавляем веб хук:

add_filter( 'gettext', 'PDFFix', 20 );

Функция:

function PDFFix($text){
    $text= str_replace(".pdf>", ".pdf#view=Fit&toolbar=0>", $text);    
    return $text;
};

Шрифты при формировании pdf из табличного документа

В виду того, что организация плавно переходит на использование свободных от лицензий шрифтов (и соответственно не попадающих на санкции), то начал работу по переводу некоторых печатных форм в 1С на новые шрифты. Сегодня столкнулся с интересной проблемой, а именно: шрифты при формировании pdf из табличного документа выставляются не верно. Проблема актуальна только при формировании PDF на «сервере». На «клиенте» — всё корректно. Например если в поле табличного документа указать шрифт PT Astra Serif, то в документе pdf они станут ArialMT:

Шрифты при формировании pdf из табличного документа

Мало того, даже если при формировании документа прямо указать шрифт…то результат тот же:

Область = Макет.ПолучитьОбласть("Шапка");
Область.Область().Шрифт=Новый Шрифт("PT Astra Serif",11);   
....
ТабДок.Область().Шрифт=Новый Шрифт("PT Astra Serif",11); 
 Вложения=Новый КоллекцияВложенийPDF();
 ТабДок.Записать(врмф , ТипФайлаТабличногоДокумента.PDF_A_3,Вложения);

Да, тут я попробовал даже использовать относительно новый функционал по сохранению PDF, именно использование формата PDF_A_3, который позволяет добавлять «вложения». Но толкового описания и примеров в сети я не нашел, а документация от 1С очень скудна. Возможно при помощи «вложений» можно прикрепить этот шрифт для использования. Но не факт.

Открыв сформировавшийся файл pdf блокнотом, можно увидеть что платформа 1С даже не пытается упомянуть нужные шрифты:

Хотя если сохранять тот-же самый табличный документ сначала в формат docx, а затем средствами Word сохранить в pdf, то всё отлично сохраняется, и PDF получается корректный:

Ну что я могу сказать? На лицо похоже ошибка в платформе. Будем ждать обновлений, а пока решил проблему формированием файла в формате html5:

 врмф=ПолучитьИмяВременногоФайла(".html");  
 ТабДок.Записать(врмф , ТипФайлаТабличногоДокумента.HTML5);
 дд = Новый ДвоичныеДанные(врмф);

Что в принципе в моём случае, проблему «не верные шрифты при формировании pdf» временно закрыло

1c: извлечение страницы из pdf документа

В настоящий момент в 1С нет встроенного средства для редактирования pdf документов, поэтому единственный выход — использовать внешние программы. Например — pdftk или ExtractPagePDF

Ниже пример реализации для ExtractPagePDF:

функция ИзвлечьСтраницуPDF(имяфайла,страница)
	answer=новый Структура("error,result",false,"");
		// вариант с ExtractPDF
		ПутьКПрограммеИзвлечения = lsОбщегоНазначенияСервер.ПутьКПрограммеРаботыСPDFФайлами();
		ИмяВременногоФайлаИзвлечения 	= ПолучитьИмяВременногоФайла("pdf");
		КаталогИзвлечения 				= ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(КаталогВременныхФайлов());			
		КодВозвратаКомпоненты = 1;
		ЗапуститьПриложение(ПутьКПрограммеИзвлечения + " 1 """ + имяфайла + """ """ + ИмяВременногоФайлаИзвлечения+""" "+Формат(страница,"ЧГ=0"), , Истина, КодВозвратаКомпоненты);			
		Если КодВозвратаКомпоненты <> 0 Тогда 				
				answer.error=true;      
				answer.result="Не удалось извлечь файлы счетов! для л/с ";
				возврат answer;
		КонецЕсли;
        answer.result=ИмяВременногоФайлаИзвлечения;	
		
		// вариант с pdftk			
		//ПутьКПрограммеИзвлечения = lsОбщегоНазначенияСервер.ПутьКПрограммеРаботыСPDFФайлами();
		//ИмяВременногоФайлаИзвлечения 	= ПолучитьИмяВременногоФайла("pdf");
		//КаталогИзвлечения 				= ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(КаталогВременныхФайлов());			
		//КодВозвратаКомпоненты = 1;      
		//страница=Формат(страница,"ЧГ=0");
		//ЗапуститьПриложение(ПутьКПрограммеИзвлечения +" """+ имяфайла + """ cat "+страница+" """ + ИмяВременногоФайлаИзвлечения+"""", , Истина, КодВозвратаКомпоненты);			
		//Если КодВозвратаКомпоненты <> 0 Тогда 				
		//		answer.error=true;      
		//		answer.result="Не удалось извлечь файлы счетов! для л/с ";
		//		возврат answer;
		//КонецЕсли;
		//answer.result=ИмяВременногоФайлаИзвлечения;	
		
		
		
	возврат answer;
конецфункции