Saya memiliki persyaratan di mana saya perlu mengunduh PDF dari situs web. PDF perlu dibuat dalam kode, yang saya pikir akan menjadi kombinasi freemarker dan kerangka kerja generasi PDF seperti iText. Ada cara yang lebih baik?
Namun, masalah utama saya adalah bagaimana cara saya mengizinkan pengguna mengunduh file melalui Spring Controller?
Jawaban:
Secara umum, ketika sudah
response.getOutputStream()
, Anda dapat menulis apa pun di sana. Anda dapat melewatkan aliran output ini sebagai tempat untuk meletakkan PDF yang dihasilkan ke generator Anda. Juga, jika Anda tahu jenis file apa yang Anda kirim, Anda dapat mengatursumber
IOUtils
bukan SpringFileCopyUtils
?Saya dapat melakukan streaming garis ini dengan menggunakan dukungan bawaan di Spring dengan ResourceHttpMessageConverter itu. Ini akan mengatur panjang konten dan tipe konten jika dapat menentukan tipe mime
sumber
Content-Disposition
tajuk dengan cara ini?Anda harus dapat menulis file pada jawaban secara langsung. Sesuatu seperti
dan kemudian tulis file tersebut sebagai aliran biner
response.getOutputStream()
. Ingatlah untuk melakukanresponse.flush()
di akhir dan itu harus dilakukan.sumber
@RequestMapping(value = "/foo/bar", produces = "application/pdf")
Dengan Spring 3.0 Anda dapat menggunakan
HttpEntity
objek kembali. Jika Anda menggunakan ini, maka pengontrol Anda tidak memerlukanHttpServletResponse
objek, dan karenanya lebih mudah untuk diuji. Kecuali ini, jawaban ini relatif sama dengan jawaban Infeligo .Jika nilai pengembalian kerangka pdf Anda adalah array byte (baca bagian kedua dari jawaban saya untuk nilai pengembalian lainnya) :
Jika jenis kembalinya PDF Anda Framework (
documentBbody
) belum menjadi array byte (dan juga tidak adaByteArrayInputStream
) maka akan bijaksana tidak untuk membuat array byte pertama. Sebaliknya lebih baik menggunakan:InputStreamResource
,PathResource
(sejak Musim Semi 4.0) atauFileSystemResource
,contoh dengan
FileSystemResource
:sumber
return new ResponseEntity<byte[]>(documentBody, headers, HttpStatus.CREATED)
ResponseEntity
adalah subkelas dariHttpEntity
(tapi saya mengerti) di sisi lain 201 DICIPTAKAN bukan yang akan saya gunakan ketika saya kembali hanya melihat ke data. (lihat w3.org/Protocols/rfc2616/rfc2616-sec10.html untuk 201 DICIPTAKAN)Jika kamu:
byte[]
sebelum mengirim ke respons;InputStream
;@ControllerAdvice
pengecualian lain untuk Anda (atau tidak).Kode di bawah ini yang Anda butuhkan:
Tentang bagian panjang file :
File#length()
harus cukup baik dalam kasus umum, tapi saya pikir saya akan membuat pengamatan ini karena memang bisa lambat , dalam hal ini Anda harus menyimpannya sebelumnya (misalnya dalam DB). Kasing bisa lambat termasuk: jika file besar, khususnya jika file tersebut dalam sistem jarak jauh atau sesuatu yang lebih rumit seperti itu - database, mungkin.InputStreamResource
Jika sumber daya Anda bukan file, misalnya Anda mengambil data dari DB, Anda harus menggunakan
InputStreamResource
. Contoh:sumber
FileSystemResource
sana. Bahkan disarankan jika sumber daya Anda adalah file . Dalam sampel ini,FileSystemResource
dapat digunakan di manaInputStreamResource
.File#length()
harus cukup baik dalam kasus umum. Saya hanya menyebutkannya karena memang bisa lambat , khususnya jika file tersebut dalam sistem jarak jauh atau sesuatu yang lebih rumit seperti itu - database, mungkin ?. Tetapi hanya khawatir jika itu menjadi masalah (atau jika Anda memiliki bukti keras itu akan menjadi satu), bukan sebelumnya. Poin utamanya adalah: Anda berupaya untuk melakukan streaming file, jika Anda harus melakukan preload semua file sebelumnya, maka streaming tidak ada bedanya, eh?Kode ini berfungsi dengan baik untuk mengunduh file secara otomatis dari pengontrol pegas pada mengklik tautan di jsp.
sumber
Kode di bawah ini berfungsi untuk saya menghasilkan dan mengunduh file teks.
sumber
Apa yang dapat saya pikirkan dengan cepat adalah, menghasilkan pdf dan menyimpannya di webapp / unduhan / <RANDOM-FILENAME> .pdf dari kode dan mengirimkan pengalihan ke file ini menggunakan HttpServletRequest
atau jika Anda dapat mengonfigurasi resolver tampilan Anda seperti,
lalu kembali saja
sumber
Solusi berikut ini cocok untuk saya
sumber
sesuatu seperti di bawah ini
Anda dapat menampilkan PDF atau mengunduhnya contoh di sini
sumber
Jika itu membantu siapa pun. Anda dapat melakukan apa yang disarankan oleh Infeligo, tetapi cukup masukkan kode tambahan ini untuk unduhan paksa.
sumber
Ini bisa menjadi jawaban yang bermanfaat.
Apakah boleh mengekspor data sebagai format pdf di frontend?
Meluas ke ini, menambahkan disposisi konten sebagai lampiran (default) akan mengunduh file. Jika Anda ingin melihatnya, Anda harus mengaturnya agar sejajar.
sumber
Dalam kasus saya, saya membuat beberapa file berdasarkan permintaan, demikian juga url harus dihasilkan.
Bagi saya bekerja seperti itu:
Sangat penting adalah ketik mime
produces
dan juga bahwa, nama file tersebut adalah bagian dari tautan sehingga Anda harus menggunakannya@PathVariable
.Kode HTML terlihat seperti itu:
Di mana
${file_name}
dihasilkan oleh Thymeleaf dalam controller dan yaitu: result_20200225.csv, sehingga seluruh url behing link adalah:example.com/aplication/dbreport/files/result_20200225.csv
.Setelah mengklik tautan, browser bertanya kepada saya apa yang harus saya lakukan dengan file - simpan atau buka.
sumber