p:dataExporter не распознает p:cellEditor
У меня есть редактируемый <p:dataTable>
с <p:cellEditor>
и я хочу экспортировать содержимое этой таблицы в формат PDF, используя <p:dataExporter>
,
Я включил банку itext 2.1.7. Я получил вывод в PDF, но он показывает Object#toString()
ценности всех <p:cellEditor>
компоненты вроде так:
org.primefaces.component.celleditor.CellEditor@1bd59e1
Как мне экспортировать выходные значения <p:cellEditor>
вместо?
2 ответа
<p:cellEditor>
действительно не признается стандартными экспортерами данных PrimeFaces. Ранее я сообщал об этом ребятам из PF как о выпуске 4013 с примером, который не только упоминает CellEditor
, но также HtmlGraphicImage
(мы используем изображения, чтобы показать логические состояния, чьи alt
мы хотели бы показать в отчетах PDF/XML/XLS/CSV).
Сначала создайте новый класс, который расширяет стандарт PDFExporter
как следует:
public class ExtendedPDFExporter extends PDFExporter {
@Override
protected String exportValue(FacesContext context, UIComponent component) {
if (component instanceof CellEditor) {
return exportValue(context, ((CellEditor) component).getFacet("output"));
}
else if (component instanceof HtmlGraphicImage) {
return (String) component.getAttributes().get("alt");
}
else {
return super.exportValue(context, component);
}
}
}
Затем, чтобы использовать его, вызовите его программно, а не через <p:dataExporter>
,
<p:dataTable binding="#{table}" editable="true" ...>
<p:column><p:cellEditor>...</p:cellEditor></p:column>
<p:column><p:cellEditor>...</p:cellEditor></p:column>
<p:column><p:cellEditor>...</p:cellEditor></p:column>
<p:column exportable="false"><p:rowEditor /></p:column>
</p:dataTable>
<h:commandLink value="PDF" action="#{bean.exportPDF(table, 'filename')}" />
С
public void exportPDF(DataTable table, String filename) throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
Exporter exporter = new ExtendedPDFExporter();
exporter.export(context, table, filename, false, false, "UTF-8", null, null);
context.responseComplete();
}
Не стесняйтесь найти таблицу данных по UIComponent#findComponent()
вместо этого и установить имя файла только в методе действия. Приведенный выше код является просто примерным.
Я согласен, я также считаю этот подход для настройки поведения Экспортера наиболее гибким и наименее болезненным.
Кто-нибудь заинтересован в использовании методов preProcessor/postProcessor с этим? Вот пример, как это сделать.
Я осмелился немного изменить метод из ответа выше:
public void exportPDF(DataTable table, String filename,
String preProcessor, String postProcessor) throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
ExpressionFactory factory = context.getApplication().getExpressionFactory();
MethodExpression preProcessorME = factory.createMethodExpression(
context.getELContext(), preProcessor, null, new Class[] {Object.class});
MethodExpression postProcessorME = factory.createMethodExpression(
context.getELContext(), postProcessor, null, new Class[] {Object.class});
Exporter exporter = new ExtendedPDFExporter();
exporter.export(context, table, filename, false, false, "UTF-8",
preProcessorMe, postProcessorME);
context.responseComplete();
}
И вот как вы используете его на своей странице (опять же, я только что изменил приведенный выше пример):
<p:dataTable binding="#{table}" editable="true" ...>
<p:column><p:cellEditor>...</p:cellEditor></p:column>
<p:column><p:cellEditor>...</p:cellEditor></p:column>
<p:column><p:cellEditor>...</p:cellEditor></p:column>
<p:column exportable="false"><p:rowEditor /></p:column>
</p:dataTable>
<h:commandLink value="PDF" action="#{bean.exportPDF(table, 'filename',
'#{yourBean.preProcessPDF}', '#{yourBean.postProcessPDF}')}" />
Обратите внимание на то, что НЕТ ВЛОЖЕННЫХ ЗАЯВЛЕНИЙ EL (что в любом случае запрещено), последние два аргумента являются простыми строками, содержащими выражения EL.