У меня есть требование, где мне нужно скачать PDF с веб-сайта. PDF должен быть сгенерирован в коде, который, как я думал, будет комбинацией freemarker и фреймворка для создания PDF, такого как iText. Есть ли лучший способ?
Тем не менее, моя основная проблема заключается в том, как разрешить пользователю загружать файл через Spring Controller?
Ответы:
Вообще говоря, когда у вас есть
response.getOutputStream()
, вы можете написать что-нибудь там. Вы можете передать этот выходной поток как место для помещения сгенерированного PDF в ваш генератор. Кроме того, если вы знаете, какой тип файла вы отправляете, вы можете установитьисточник
IOUtils
вместо SpringFileCopyUtils
?Мне удалось поточить это, используя встроенную поддержку Spring с ResourceHttpMessageConverter. Это установит content-length и content-type, если это может определить mime-тип
источник
Content-Disposition
заголовок таким образом?Вы должны быть в состоянии написать файл в ответе напрямую. Что-то вроде
а затем записать файл в виде двоичного потока
response.getOutputStream()
. Не забудьте сделатьresponse.flush()
в конце, и это должно сделать это.источник
@RequestMapping(value = "/foo/bar", produces = "application/pdf")
В Spring 3.0 вы можете использовать
HttpEntity
возвращаемый объект. Если вы используете это, то ваш контроллер не нуждается вHttpServletResponse
объекте, и, следовательно, его проще тестировать. Кроме этого, этот ответ является относительным равен ответ Infeligo .Если возвращаемое значение вашей pdf-фреймворки является байтовым массивом (прочитайте вторую часть моего ответа для других возвращаемых значений) :
Если тип возвращаемого значения вашей PDF Framework (
documentBbody
) уже не является байтовым массивом (а также нетByteArrayInputStream
), то было бы разумно НЕ делать его сначала байтовым массивом. Вместо этого лучше использовать:InputStreamResource
,PathResource
(начиная с весны 4.0) илиFileSystemResource
,пример с
FileSystemResource
:источник
return new ResponseEntity<byte[]>(documentBody, headers, HttpStatus.CREATED)
ResponseEntity
это подклассHttpEntity
(но я понимаю) 201 CREATED - это не то, что я использовал бы, когда возвращал просто представление данных. (см. w3.org/Protocols/rfc2616/rfc2616-sec10.html для 201 CREATED)Если ты:
byte[]
перед отправкой ответа;InputStream
;@ControllerAdvice
исключения для вас (или нет).Код ниже - то, что вам нужно:
О части длины файла :
File#length()
должно быть достаточно хорошо в общем случае, но я подумал, что сделаю это наблюдение, потому что оно может быть медленным , и в этом случае вы должны сохранить его ранее (например, в БД). Случаи, которые могут быть медленными, включают: если файл большой, особенно если файл находится в удаленной системе или что-то более сложное, например, - база данных, может быть.InputStreamResource
Если ваш ресурс не является файлом, например, вы берете данные из БД, вы должны использовать
InputStreamResource
. Пример:источник
FileSystemResource
там. Это даже рекомендуется, если ваш ресурс представляет собой файл . В этом примереFileSystemResource
может быть использовано гдеInputStreamResource
есть.File#length()
должно быть достаточно хорошо в общем случае. Я только что упомянул об этом, потому что он может быть медленным , особенно если файл находится в удаленной системе или что-то более сложное, например, база данных, может быть? Но только беспокойтесь, если это станет проблемой (или если у вас есть веские доказательства, она станет такой), не раньше. Суть в том, что вы прилагаете усилия для потоковой передачи файла, если вам нужно предварительно загрузить все это раньше, тогда потоковая передача завершается без разницы, а?Этот код прекрасно работает для автоматической загрузки файла с контроллера Spring при нажатии на ссылку на jsp.
источник
Ниже код работал для меня, чтобы сгенерировать и загрузить текстовый файл.
источник
Я могу быстро придумать, сгенерировать pdf и сохранить его в файле webapp / downloads / <RANDOM-FILENAME> .pdf из кода и отправить пересылку в этот файл с помощью HttpServletRequest.
или если вы можете настроить свой видоискатель что-то вроде,
тогда просто вернись
источник
Следующее решение работает для меня
источник
что-то вроде ниже
Вы можете отобразить PDF или скачать его примеры здесь
источник
Если это кому-нибудь поможет. Вы можете сделать то, что предложил принятый Infeligo ответ, но просто добавить этот дополнительный бит в код для принудительной загрузки.
источник
Это может быть полезным ответом.
Можно ли экспортировать данные в формате PDF в веб-интерфейс?
В дополнение к этому добавление размещения содержимого в качестве вложения (по умолчанию) приведет к загрузке файла. Если вы хотите просмотреть его, вам нужно установить его в строку.
источник
В моем случае я создаю некоторый файл по требованию, поэтому также должен быть создан URL.
Для меня работает нечто подобное:
Очень важен тип mime,
produces
а также то, что это имя файла является частью ссылки, поэтому вы должны использовать его@PathVariable
.HTML-код выглядит так:
Где
${file_name}
генерируется Thymeleaf в контроллере и есть: result_20200225.csv, так что весь URL опережать ссылка:example.com/aplication/dbreport/files/result_20200225.csv
.После нажатия на ссылку браузер спросит меня, что делать с файлом - сохранить или открыть.
источник