Jasper Report Java: избегайте разрывов слов при переносе

У меня есть проект Java, который компилирует Jasper XML на лету, а затем экспортирует в PDF.

В одном из текстовых полей мне нужно, чтобы JasperReports не вырезал слова, а адаптировал размер шрифта. Изменение размера шрифта работает нормально, когда текст большой, Джаспер уменьшает шрифт и оборачивает текст, но часть «не обрезать слова» не работает, во многих случаях PDF будет содержать текст в несколько строк, но перенос будет резать слова в очень нелогичной части, даже иногда просто оставляя одну букву слова на следующей строке. Можете ли вы сказать мне, что я делаю неправильно?

Я добавил и проверил все параметры, которые я нашел в документации Jasper и с помощью Google о разрывах слов, но ни один из них или любая их комбинация не меняют результаты.

Виновник текстового поля здесь:

<textField textAdjust = "ScaleFont" isBlankWhenNull = "true">
    <reportElement stretchType = "ElementGroupBottom" x = "10" y = "124" width = "771"
     height = "396" isPrintInFirstWholeBand = "true" isPrintWhenDetailOverflows = "true"
     uuid = "bb2d4ab6-fc46-4edd-87ad-18dc4d32d461">
        <property name = "net.sf.jasperreports.print.keep.full.text" value = "Boolean.TRUE"/>
        <property name = "net.sf.jasperreports.print.html.wrap.break.word" value = "Boolean.FALSE"/>
        <property name = "net.sf.jasperreports.text.save.line.breaks" value = "Boolean.FALSE"/>
    </reportElement>
    <textElement textAlignment = "Center" verticalAlignment = "Middle" markup = "html">
        <font size = "140" isBold = "true"/>
    </textElement>
    <textFieldExpression><![CDATA[$P{letrero}]]></textFieldExpression>
</textField>

Часть Java, которая генерирует отчет, находится здесь:

try {
    parameters.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, entityManager);
    JasperReport report = JasperCompileManager.compileReport(Util.getFileInClassPathAsInputStream("/web/report/name-sign.jrxml"));
    
    JasperPrint print = JasperFillManager.fillReport(report, parameters, new JREmptyDataSource());
    
    return JasperExportManager.exportReportToPdf(print);
} catch (JRException ex) {
    ex.printStackTrace();
    logger.error( ex.getMessage());
}
return null;

Разве эти свойства не должны иметь value = "true"/value = "false" вместо value = "Boolean.TRUE"/value = "Boolean.FALSE"?

Mark Rotteveel 12.04.2023 12:14

также попробовал, как вы сказали, и тот же результат, в любом случае оба должны работать, этот формат используется во всех наших отчетах для других параметров в другом отчете и, похоже, работает с этим форматом...

Vinz 13.04.2023 18:55
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел эту спецификацию Jasper Reports:

https://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/fill/TextMeasurer.html

Говоря о большинстве других доступных параметров для обтекания текстом, мы добавили свойство:

<property name = "net.sf.jasperreports.text.truncate.at.char" value = "false"/>

исходя из того, что я мог понять из спецификаций, это говорит яшме не ломать символы, а только слова ... И проблема решена!

полное текстовое поле теперь выглядит так:

<textField textAdjust = "ScaleFont" isBlankWhenNull = "true">
                <reportElement stretchType = "ElementGroupBottom" x = "10" y = "124" width = "771" height = "396" isPrintInFirstWholeBand = "true" isPrintWhenDetailOverflows = "true" uuid = "bb2d4ab6-fc46-4edd-87ad-18dc4d32d461">
                    <property name = "net.sf.jasperreports.print.keep.full.text" value = "false"/>
                    <property name = "net.sf.jasperreports.text.save.line.breaks" value = "true"/>
                    <property name = "net.sf.jasperreports.export.pdf.force.linebreak.policy" value = "true"/>
                    <property name = "net.sf.jasperreports.text.truncate.at.char" value = "false"/>
                </reportElement>
                <textElement textAlignment = "Center" verticalAlignment = "Middle" markup = "html">
                    <font pdfFontName = "Helvetica" size = "136" isBold = "true" isPdfEmbedded = "true"/>
                </textElement>
                <textFieldExpression><![CDATA[$P{letrero}]]></textFieldExpression>
    </textField>

Надеюсь, это поможет любому, у кого есть похожая проблема!

Обновлено: эта конфигурация решила проблему в некоторых, но не во всех ситуациях, если текст помещается в 2 строки, перенося один карат первого слова, Джаспер все равно предпочтет сделать это, чем немного уменьшить шрифт, но теперь, по крайней мере, если перенос одного символа происходил во второй или третьей строке, теперь поведение соответствует ожидаемому, и яшма скорее немного уменьшит размер шрифта, чем перенесет одну цифру в новую строку... Я думаю, что алгоритм «ScaleFont» и «Truncate» политики просто испытывают трудности в совместной работе. Поэтому, если кто-то найдет лучшее решение, работающее всегда, меня все равно интересует лучший ответ, чем тот, который я нашел.

Обновлено еще раз: найдено окончательное решение, проблема заключалась в проблеме со шрифтом, добавление: pdfFontName="Helvetica" в текстовый элемент работает до сих пор. Я думаю, что без указания шрифта Jasper устанавливает требуемое масштабирование на основе своего шрифта по умолчанию, а затем, если в PDF-файле есть возможность выбрать немного другой шрифт, масштабирование, определенное Jasper, может не дать ожидаемого эффекта. Ну, просто предполагая эту часть...

Другие вопросы по теме