#java #spring-mvc #itext
#java #spring-mvc #itext
Вопрос:
У меня есть веб-приложение Java, основанное на Spring MVC. Задача состоит в том, чтобы сгенерировать файл pdf. Как всем известно, движок spring имеет собственную встроенную библиотеку iText, поэтому сгенерировать PDF-файл действительно просто. Прежде всего, нам нужно перегрузить AbstractView и создать некоторый PDFView. И вторая вещь заключается в том, чтобы использовать это представление в контроллере. Но в моем приложении я также должен иметь возможность сохранять сгенерированные PDF-файлы на локальном диске или предоставлять моим пользователям некоторую ссылку для загрузки этого файла. Таким образом, представление в этом случае мне не подходит.
Я хочу создать какой-нибудь универсальный генератор pdf, который создает PDF-файл и возвращает массив байтов. Таким образом, я могу использовать этот массив для хранения файлов (на жестком диске) или распечатать его непосредственно в браузере. И вопрос в том, есть ли какой-либо способ использовать такой движок (который возвращает только массив байтов) в решении PDFView? Я спрашиваю, потому что перегруженный метод buildPdfDocument (в PDFView) уже имеет параметры PdfWriter и Document. Спасибо
Ответ №1:
tldr; вы должны иметь возможность использовать представление и сохранять его в файл.
Попробуйте использовать Flying Saucer и его ITextRenderer при перегрузке AbstractPdfView.
import org.xhtmlrenderer.pdf.ITextRenderer;
public class MyAbstractView extends AbstractView {
OutputStream os;
public void buildPdfDocument(Map<String,Object> model, com.lowagie.text.Document document, com.lowagie.text.pdf.PdfWriter writer, HttpServletRequest request, HttpServletResponse response){
//process model params
os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
String url = "http://www.mysite.com"; //set your sample url namespace here
renderer.setDocument(document, url); //use the passed in document
renderer.layout();
renderer.createPDF(os);
os.close();
}
}
protected final void renderMergedOutputModel(Map<String,Object> model,
HttpServletRequest request,
HttpServletResponse response)
throws Exception{
if(os != null){
response.outputStream = os;
}
public byte[] getPDFAsBytes(){
if(os != null){
byte[] stuff;
os.write(stuff);
return stuff;
}
}
}
Вероятно, вам придется изменить показанный здесь пример реализации, но это должно обеспечить основную суть.
Комментарии:
1. Спасибо за ваш ответ. К сожалению, я не использую grails. Кто-нибудь знает, как это реализовать на «чистой» java spring?
2. Grails — это просто Spring MVC и другие материалы в Groovy, которые очень похожи на Java. Этот ответ предназначен для того, чтобы вы могли создать аналогичную функциональность, проверив исходный код библиотеки, который доступен по адресу svn.codehaus.org/grails-plugins/grails-rendering/trunk . Загрузите версию 0.3 и посмотрите конкретно на PdfRenderingService и его родительский класс, и вы увидите, что он по сути аналогичен чистой Java.
3. Для рендеринга просто используется Flying Saucer under the covers, в котором есть довольно хороший учебник о том, как вы могли бы использовать его специально для создания выходного потока. Проверьте ссылку.
4. Не могли бы вы предоставить какой-нибудь пример кода, как это выглядит в контроллере? Особенно та часть, где вы сохраняете представление в файле?
5. Контроллер — это просто класс, на который возложена конкретная ответственность за посредничество между моделями и представлениями. Следовательно, работа с файлами в нем должна работать так же, как и в любом другом классе, где вы записываете содержимое массива байтов в файл. Я уверен, что вы можете поискать в Google примеры написания файлов. Однако, как правило, эта работа должна выполняться в службе приложений , а не в контроллере. Контроллер должен делегировать службе (передавая массив байтов), которая обрабатывает эту операцию. Плагин для рендеринга был выбран потому, что он очень четко показывает, как добиться такого приятного разделения задач