Сравнивая входные данные json с выходными данными, становится ясно, что вы не можете точно извлечь json из PDF-файлов, сгенерированных вашим текущим кодом.
Проблемы возникают, когда рендеринг строки в PDF добавляет разрывы строк, чтобы текст не попал на поля. Каждый разрыв строки в результате, возможно, уже был во входной строке или был введен iText, и в общем случае это невозможно распознать.
Если iText прервал строку в пробеле или пунктуация (двоеточие, запятая, скобка) за пределами имени или значения, эти дополнительные разрывы строк не меняют смысла объекта json, но разрывы строк внутри имен и значений - это отдельная история.
Даже если бы мы могли предположить, что в именах или значениях нет разрывов строк (фактически в значениях в json, которые вы разделяли, есть разрывы строк в значениях, но эти разрывы строк могли закрасться из-за как вы поделились), и, следовательно, мы могли бы просто удалить их, некоторые из этих разрывов строк были применены там, где в исходном значении был пробел, а другие нет. Там, где в пробеле строка разбита, этот пробел отбрасывается и больше не появляется в конечном выводе. И опять же, в общем случае это невозможно распознать, что имеет место только с извлеченным выводом.
Таким образом, точное извлечение невозможно.
Как следствие, у вас есть изменить способ встраивания json в PDF. Поскольку вы не упомянули, почему вы делаете это вообще, и какие альтернативные варианты у вас есть, я не могу дать окончательное предложение, просто представлю некоторые варианты, которые могут или не могут быть совместимы с вашими требованиями:
- Встроить json не как обычный, stati c контент страницы, а как значение текстового поля многострочной формы. Значения в полях формы могут быть точно извлечены из PDF.
- В дополнение к видимому json в содержимом страницы, также вставьте json в объект частного потока в PDF; затем вы можете точно извлечь json из этого объекта потока.
- Используйте размер шрифта настолько мал, что iText не добавляет разрывов строк во время рендеринга. (Однако, скорее всего, результат будет слишком мал для чтения без увеличения.)
- Визуализируйте json вручную (используя низкоуровневые API-интерфейсы iText) и каким-то образом отметьте добавленные разрывы строк и пропущенные пробелы. Во время извлечения вы должны реагировать на эти маркеры.
Например, чтобы реализовать опцию 1, встраивая json как значение текстового поля многострочной формы , просто добавьте его так:
Document document = new Document();
document.setPageSize(PageSize.A4);
document.addCreationDate();
document.addAuthor("Me");
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(jsonPdfFile));
document.open();
pdfWriter.getAcroForm().setNeedAppearances(true);
TextField textField = new TextField(pdfWriter, document.getPageSize(), "json");
textField.setOptions(TextField.MULTILINE | TextField.READ_ONLY);
PdfFormField field = textField.getTextField();
field.setValueAsString(originalJson);
pdfWriter.addAnnotation(field);
document.close();
и извлеките его снова вот так:
PdfReader pdfReader = new PdfReader(jsonPdfFile.getAbsolutePath());
String jsonBody = pdfReader.getAcroFields().getField("json");
pdfReader.close();
( Извлечение Json тест testJsonToPdfToJsonFormField
)
Я использую текущую ветку разработки iText 5.5.14-SNAPSHOT. Код должен работать с любой версией 5.5.x.