Как показать / скрыть столбец во время выполнения?
Я хотел бы показать / скрыть столбец во время выполнения в зависимости от конкретного условия. Я использую "Печатать при выражении", чтобы условно показать / скрыть этот столбец (и его заголовок) в моем отчете. Когда столбец скрыт, пространство, которое он занимал бы, остается пустым, что не особенно привлекательно.
Я бы предпочел, если бы дополнительное пространство использовалось более эффективно, возможности включают в себя:
- ширина отчета уменьшается на ширину скрытого столбца
- дополнительное пространство распределяется между оставшимися столбцами
Теоретически, я мог бы достичь первого, установив ширину столбца (и заголовка) в 0, но также указать, что размер столбца должен соответствовать его содержанию. Но JasperReports не предоставляет опцию "изменить размер под размер содержимого".
Другой возможностью является создание отчетов с использованием API-интерфейса Jasper вместо определения шаблона отчета в XML. Но это кажется большим усилием для такого простого требования.
8 ответов
В более поздней версии (v5 или выше) отчетов о яшме вы можете использовать jr:table
компонент и по- настоящему достичь этого (без использования Java-кода, как с использованием dynamic-jasper или динамических отчетов).
Метод использует <printWhenExpression/>
под <jr:column/>
пример
Пример данных
+----------------+--------+
| User | Rep |
+----------------+--------+
| Jon Skeet | 854503 |
| Darin Dimitrov | 652133 |
| BalusC | 639753 |
| Hans Passant | 616871 |
| Me | 6487 |
+----------------+--------+
Образец jrxml
Примечание: параметр $P{displayRecordNumber}
и <printWhenExpression>
под первым jr:column
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="reputation" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="a88bd694-4f90-41fc-84d0-002b90b2d73e">
<style name="table">
<box>
<pen lineWidth="1.0" lineColor="#000000"/>
</box>
</style>
<style name="table_TH" mode="Opaque" backcolor="#F0F8FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="table_CH" mode="Opaque" backcolor="#BFE1FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="table_TD" mode="Opaque" backcolor="#FFFFFF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<subDataset name="tableDataset" uuid="7a53770f-0350-4a73-bfc1-48a5f6386594">
<field name="User" class="java.lang.String"/>
<field name="Rep" class="java.math.BigDecimal"/>
</subDataset>
<parameter name="displayRecordNumber" class="java.lang.Boolean">
<defaultValueExpression><![CDATA[true]]></defaultValueExpression>
</parameter>
<queryString>
<![CDATA[]]>
</queryString>
<title>
<band height="50">
<componentElement>
<reportElement key="table" style="table" x="0" y="0" width="555" height="47" uuid="76ab08c6-e757-4785-a43d-b65ad4ab1dd5"/>
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<datasetRun subDataset="tableDataset" uuid="07e5f1c2-af7f-4373-b653-c127c47c9fa4">
<dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
</datasetRun>
<jr:column width="90" uuid="918270fe-25c8-4a9b-a872-91299cddbc31">
<printWhenExpression><![CDATA[$P{displayRecordNumber}]]></printWhenExpression>
<jr:columnHeader style="table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="90" height="30" uuid="5cd6da41-01d5-4f74-99c2-06784f891d1e"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Record number]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="table_TD" height="30" rowSpan="1">
<textField>
<reportElement x="0" y="0" width="90" height="30" uuid="5fe48359-0e7e-44b2-93ac-f55404189832"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$V{REPORT_COUNT}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="90" uuid="7979d8a2-4e3c-42a7-9ff9-86f8e0b164bc">
<jr:columnHeader style="table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="90" height="30" uuid="61d5f1b6-7677-4511-a10c-1fb8a56a4b2a"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Username]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="table_TD" height="30" rowSpan="1">
<textField>
<reportElement x="0" y="0" width="90" height="30" uuid="a3cdb99d-3bf6-4c66-b50c-259b9aabfaef"/>
<box leftPadding="3" rightPadding="3"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{User}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="90" uuid="625e4e5e-5057-4eab-b4a9-c5b22844d25c">
<jr:columnHeader style="table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="90" height="30" uuid="e1c07cb8-a44c-4a8d-8566-5c86d6671282"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Reputation]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="table_TD" height="30" rowSpan="1">
<textField pattern="#,##0">
<reportElement x="0" y="0" width="90" height="30" uuid="6be2d79f-be82-4c7b-afd9-0039fb8b3189"/>
<box leftPadding="3" rightPadding="3"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{Rep}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
</componentElement>
</band>
</title>
</jasperReport>
Вывод с $P{displayRecordNumber}=true
Вывод с $P{displayRecordNumber}=false
Как видите, колонки хорошо адаптируются, на основании чего отображаются.
JasperDesign используется для изменения объекта шаблона (JasperReport) из кода во время выполнения. Я думаю, это может соответствовать вашему случаю.
Удалить строку, когда пусто: эта опция убирает вертикальное пространство, занимаемое объектом, если оно не видно; видимость элемента определяется значением выражения, содержащегося в атрибуте "Печатать при выражении". Думайте о странице как о сетке, в которой размещены элементы, а линия - это пространство, занимаемое элементом. Рисунок 4-17 показывает линию элемента A; чтобы действительно удалить эту строку, все элементы, которые разделяют часть строки, должны быть нулевыми (то есть они не будут напечатаны).
Я рекомендую использовать DynamicReports, он с открытым исходным кодом и основан на JasperReports. Основным преимуществом этой библиотеки является динамический дизайн отчетов и отсутствие необходимости в визуальном дизайнере отчетов.
Небольшое изменение в теме "второго отчета", которую я использовал, состоит в том, чтобы изолировать часть отчета, где у вас есть необязательный столбец, в свой собственный подотчет, а затем создать два подотчета, один с и один без столбца, а затем использовать условия для определения, какой подотчет печатать.
Проверьте это. В этом уроке они используют шаблон XML с платформой Velocity. Это довольно сложно. А чтобы сделать это проще, вы можете использовать DynamicJasper. Эта библиотека представляет собой Java API с открытым исходным кодом, который работает над JasperReports и решает проблему динамических столбцов.
Если это всего один столбец, можно ли разместить этот столбик справа, а затем использовать печать при выражении. Таким образом, в середине нет дыры. Я знаю, что это не идеально, так как я пытался сделать то, что вы пытаетесь сделать в прошлом, и не смог найти то, что я называю хорошим решением.
Второй идеей было бы создание второго отчета на основе первого без столбца, а затем при вызове отчета проверьте условие, чтобы решить, какой из них вызывать. Опять не идеально, но будет работать.
Я знаю, что это не тот ответ, который вы искали, но одно из этих предложений может помочь вам.
Я думаю, что этот ответ приходит слишком поздно, но я добавляю его для записи. В моем случае я мог бы решить это без каких-либо дополнительных зависимостей или инструментов. В файле JRXML я просто добавил ширину текстовых полей динамическую ширину несколько раз. Один раз за возможную ширину. Затем в каждом текстовом поле я установил, что оно должно быть напечатано только в случае определенного условия.
Это может быть не так элегантно, как динамическое задание ширины, но без дополнительных библиотек справится с задачей.