Простая библиотека Java для сравнения двух файлов PDF. Файлы визуализируются и сравниваются попиксельно. Нет сравнения текстов.
Просто включите его как зависимость. Пожалуйста, проверьте наличие самой последней доступной версии:
< dependencies >
< dependency >
< groupId >de.redsix</ groupId >
< artifactId >pdfcompare</ artifactId >
< version >...</ version > <!-- see current version in the maven central tag above -->
</ dependency >
</ dependencies >
Существует простой интерактивный пользовательский интерфейс, когда вы запускаете файл jar без каких-либо дополнительных аргументов (который запускает класс de.redsix.pdfcompare.Main). Это позволяет вам выбирать файлы для сравнения, а также отмечать области, которые следует игнорировать, и записывать их в файл игнорирования.
Рядом с пользовательским интерфейсом вы можете предоставить ожидаемый и фактический файл, а также дополнительные параметры через CLI. Чтобы получить справку по CLI, используйте опцию -h или --help-.
usage: java -jar pdfcompare-x.x.x-full.jar [EXPECTED] [ACTUAL]
-h,--help Displays this text and exit
...
Но PdfCompare фокусируется на встроенном использовании в качестве библиотеки.
new PdfComparator ( "expected.pdf" , "actual.pdf" ). compare (). writeTo ( "diffOutput" );
В результате будет создан выходной PDF-файл, который может включать пометки для обнаруженных различий. PdfCompare преобразует страницу из ожидаемого файла PDF и ту же страницу из фактического файла PDF в растровое изображение и сравнивает эти два изображения попиксельно. Одинаковые пиксели немного блекнут. Отличающиеся пиксели отмечены красным и зеленым. Зелёным цветом обозначены пиксели, которые есть в ожидаемом PDF-файле, но отсутствуют в фактическом PDF-файле. Красным цветом обозначены пиксели, которые присутствуют в фактическом.pdf, но не присутствуют в ожидаемом.pdf. По краям бумаги есть отметки пурпурного цвета, позволяющие быстро находить области, которые отличаются друг от друга. Игнорируемые области отмечены желтым фоном. Страницы, которые ожидались, но не пришли, отмечены красной рамкой. Страницы, которые появляются, но не ожидались, отмечаются зеленой рамкой.
Метод сравнения возвращает CompareResult, который можно запросить:
final CompareResult result = new PdfComparator ( "expected.pdf" , "actual.pdf" ). compare ();
if ( result . isNotEqual ()) {
System . out . println ( "Differences found!" );
}
if ( result . isEqual ()) {
System . out . println ( "No Differences found!" );
}
if ( result . hasDifferenceInExclusion ()) {
System . out . println ( "Differences in excluded areas found!" );
}
result . getDifferences (); // returns page areas, where differences were found
Для удобства writeTo также возвращает статус равенства:
boolean isEquals = new PdfComparator ( "expected.pdf" , "actual.pdf" ). compare (). writeTo ( "diffOutput" );
if (! isEquals ) {
System . out . println ( "Differences found!" );
}
Метод сравнения можно вызвать с именами файлов, такими как строки, файлы, пути или входные потоки.
Также можно определить прямоугольные области, которые игнорируются при сравнении. Для этого необходимо создать файл, в котором определяются области, которые следует игнорировать. Формат файла — JSON (или расширенный набор под названием HOCON) и имеет следующую форму:
exclusions: [
{
page : 2
x1 : 300 // entries without a unit are in pixels. Pdfs are rendered by default at 300DPI
y1 : 1000
x2 : 550
y2 : 1300
} ,
{
// page is optional. When not given, the exclusion applies to all pages.
x1 : 130.5 mm // entries can also be given in units of cm, mm or pt (DTP-Point defined as 1/72 Inches)
y1 : 3.3 cm
x2 : 190 mm
y2 : 3.7 cm
} ,
{
page : 7
// coordinates are optional. When not given, the whole page is excluded.
}
]
Если предоставленный файл исключений не найден, он игнорируется и сравнение выполняется без исключений.
Исключения предусмотрены в кодексе следующим образом:
new PdfComparator ( "expected.pdf" , "actual.pdf" ). withIgnore ( "ignore.conf" ). compare ();
В качестве альтернативы исключение можно добавить через API следующим образом:
new PdfComparator ( "expected.pdf" , "actual.pdf" )
. withIgnore ( new PageArea ( 1 , 230 , 350 , 450 , 420 ))
. withIgnore ( new PageArea ( 2 ))
. compare ();
Если вы хотите сравнить PDF-файлы, защищенные паролем, вы можете передать пароль компаратору с помощью методов withExpectedPassword (строковый пароль) или withActualPassword (строковый пароль) соответственно.
new PdfComparator ( "expected.pdf" , "actual.pdf" )
. withExpectedPassword ( "somePwd" )
. withActualPassword ( "anotherPwd" )
. compare ();
PdfCompare можно настроить с помощью файла конфигурации. Файл конфигурации по умолчанию называется «application.conf» и должен находиться в корне пути к классам.
PdfCompare использует Lightbend Config (ранее называвшийся TypeSafe Config) для чтения файлов конфигурации. Если вы хотите указать другой файл конфигурации, вы можете узнать больше об этом здесь: https://github.com/lightbend/config#standard-behavior. В частности, вы можете указать замену файла конфигурации с помощью аргумента командной строки -Dconfig.file=path/to/file.
Альтернативно вы можете указать параметры либо через переменные системной среды, либо как параметр Jvm с -DvariableName=
Другой способ программно указать другое расположение конфигурации — создать новый ConfigFileEnvironment(...) и передать его в PdfCompare.withEnvironment(...).
Все настройки, которые можно изменить через файл application.conf, также можно изменить программно через API. Для этого вы можете использовать следующий код:
new PdfComparator ( "expected.pdf" , "actual.pdf" )
. withEnvironment ( new SimpleEnvironment ()
. setActualColor ( Color . green )
. setExpectedColor ( Color . blue ))
. compare ();
SimpleEnvironment делегирует все параметры, которые не были назначены, среде по умолчанию.
Через среду можно настроить параметры памяти (см. выше) и следующие настройки:
ДПИ=300
Устанавливает DPI, с которым отображаются страницы PDF. По умолчанию — 300.
ожидаемый цвет=00B400 (ЗЕЛЕНЫЙ)
Ожидаемый цвет — это цвет, который используется для ожидаемых, но отсутствующих пикселей. Цвета указаны в формате HTML-Stlye (без начального символа «#»). Первые два символа определяют красную часть цвета в шестнадцатеричном виде. Следующие два символа определяют зеленую часть цвета. Последние два символа определяют синюю часть используемого цвета.
актуальныйЦвет=D20000 (КРАСНЫЙ)
Фактический цвет — это цвет, который используется для пикселей, которые присутствуют, но не ожидаются. Цвета указаны в формате HTML-Stlye (без начального символа «#»). Первые два символа определяют красную часть цвета в шестнадцатеричном виде. Следующие два символа определяют зеленую часть цвета. Последние два символа определяют синюю часть используемого цвета.
tempDir=System.property("java.io.tmpdir")
Устанавливает каталог, в который будут записываться временные файлы. По умолчанию используется значение по умолчанию Java для java.io.tmpdir, которое обычно определяет системное значение по умолчанию, например /tmp в большинстве систем Unix.
разрешенныйDifferenceInPercentPerPage=0,2
Процент пикселей, которые могут различаться на странице. По умолчанию — 0. Если по какой-то причине ваш рендеринг немного некорректен или вы допускаете некоторую погрешность, вы можете настроить процент пикселей, которые игнорируются во время сравнения. Таким образом, о разнице сообщается только в том случае, если разница превышает заданный процент пикселей. Процент рассчитывается за страницу. Не то чтобы различия по-прежнему отмечались в выходном файле, когда вы добавляетеEqualPagesToResult.
параллельная обработка = истина
Если установлено значение false, отключает всю параллельную обработку и обрабатывает все в одном потоке.
addEqualPagesToResult=истина
Если установлено значение false, к результату добавляются только страницы с различиями, и это получается PDF-документ с различиями.
failOnMissingIgnoreFile=false
Если установлено значение true, отсутствие игнорируемого файла приводит к исключению. В противном случае оно игнорируется и записываются только сообщения журнала информационного уровня.
Существует несколько различных реализаций CompareResults с разными характеристиками. Его можно использовать для управления определенными аспектами поведения системы, в частности потреблением памяти.
При использовании PdfCompare полезно знать некоторые внутренние особенности. Вот в двух словах, что делает PdfCompare, когда сравнивает два PDF-файла.
PdfCompare использует библиотеку Apache PdfBox для чтения и записи PDF-файлов.
Поэтому сравнение больших PDF-файлов может занять много памяти. Я еще не нашел способа поэтапно писать разницу в PDF-файле постранично с помощью PdfBox, но есть некоторые обходные пути.
В настоящее время существует два разных метода CompareResults, которые имеют разные стратегии замены страниц на диск и тем самым ограничения потребления памяти.
Другая реализация CompareResult может использоваться следующим образом:
new PdfComparator ( "expected.pdf" , "actual.pdf" , new CompareResultWithPageOverflow ()). compare ();
Также есть некоторые внутренние настройки ограничений памяти, которые можно изменить. Просто добавьте файл с именем «application.conf» в корень пути к классам. Этот файл может иметь некоторые или все следующие настройки, чтобы перезаписать значения по умолчанию, указанные здесь:
imageCacheSizeCount=30
Сколько изображений кэшируется PdfBox
maxImageSizeInCache=100000
Приблизительный максимальный размер кэшируемых изображений, чтобы предотвратить кэширование очень больших изображений.
mergeCacheSizeMB=100
Когда PDF-файлы частично записываются, а затем объединяются, это кэш памяти, настроенный для экземпляра PdfBox, который выполняет объединение.
swapCacheSizeMB=100
Когда PDF-файлы записываются частично, это кэш памяти, настроенный для экземпляра PdfBox, выполняющего частичную запись.
документCacheSizeMB=200
Это размер кэша, настроенный для экземпляра PdfBox, который загружает сравниваемые документы.
параллельная обработка = истина
Если установлено значение false, отключает всю параллельную обработку и обрабатывает все в одном потоке.
общийTimeoutInMinutes=15
Установите общий тайм-аут. Это мера безопасности для обнаружения возможных взаимоблокировок. Сложные сравнения могут занять больше времени, поэтому это значение, возможно, придется увеличить.
executorTimeoutInSeconds=60
Устанавливает тайм-аут ожидания завершения выполнения исполнителями после достижения общего времени ожидания. Вряд ли вам когда-нибудь понадобится это изменить.
Таким образом, в этой конфигурации по умолчанию PdfBox должен использовать до 400 МБ оперативной памяти для своих кешей перед переключением на диск. У меня есть хороший опыт предоставления JVM кучи размером 2 ГБ.
Большое спасибо Четану Рао [email protected] за помощь в диагностике проблем с нехваткой памяти и идею частичной записи и объединения созданных PDF-файлов.