Pertanyaan Baca BLOB (Konten PDF) dari database dan edit dan output file PDF yang diedit tanpa membuat file fisik


Saya menggunakan Database Oracle dan menyimpan konten PDF dalam bidang BLOB.

Saya ingin membaca konten BLOB dan kemudian mengedit dan menampilkan konten yang diedit.

Pengeditan yang harus saya lakukan adalah:

  • tambahkan judul di atas konten BLOB
  • tambahkan tanda Air di setiap halaman
  • tambahkan footer di setiap halaman

Kemudian saya harus menampilkan file tanpa file fisik yang dibuat yang ada dalam aliran respons.

Saya mencoba untuk mencapainya dengan menggunakan teks ini tetapi tidak sampai ke mana pun dengannya. Saya terjebak dan tidak yakin harus mulai dari mana.

Juga kadang-kadang saya mungkin harus menggabungkan konten gumpalan menjadi satu, tapi itulah beberapa hal yang pasti akan terjadi Sekali dalam sejuta ... jadi itu bukan masalah sekarang ...

Bagaimana saya bisa mencapai persyaratan utama saya dari ketiga langkah di atas menggunakan di java? Apakah mungkin dengan Itext ?? Atau apakah ada perpustakaan lain yang tersedia yang akan membantu?

Database: Oracle 10g Release 2

OS: Linux Fedora / Redhat

Front-end: Java / Servlet / JSP

EDIT

Inilah yang saya coba lakukan

oracle.sql.BLOB blob = (BLOB) rs.getBlob("MYPDF");
byte[] bytes = blob.getBytes(1, (int) blob.length());
InputStream is = blob.getBinaryStream();
Document document=new Document();
ServletOutputStream servletOutputStream = response.getOutputStream();
PdfWriter writer=PdfWriter.getInstance(document, servletOutputStream);
document.open();
document.add(new Paragraph("Some title"));
document.add(new Paragraph("Some title"));
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
document.close();

Program ini menampilkan isi pdf di bidang BLOB dalam basis data dan tanpa judul.

dan ketika saya mengubah sedikit di kode (mengubah urutan beberapa baris terakhir) menjadi:

document.close();
servletOutputStream.flush();
servletOutputStream.close();

Saya mendapatkan dokumen dengan konten judul di dalamnya dan tidak ada konten pdf bidang BLOB. Hal pertama (servletoutputstream / dokumen) yang tertutup telah dibuang sebagai output.

Dan ketika saya menutup dokumen sebelum menempatkan konten gumpalan di outputstream:

document.close();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();

Saya mendapati browser menampilkan sesuatu seperti ini:

%PDF-1.4 %���� 2 0 obj <>stream x�+�r �26S�00SI�2P�5��1���BҸ4��sSJ2KrR5C��*P�B�5�+��k)&� endstream endobj 4 0 obj <<<>>>/MediaBox[0 0 595 842]>> endobj 1 0 obj <> endobj 3 0 obj <> endobj 5 0 obj <> endobj 6 0 obj <> endobj xref 0 7 0000000000 65535 f 0000000304 00000 n 0000000015 00000 n 0000000392 00000 n 0000000147 00000 n 0000000443 00000 n 0000000488 00000 n trailer <]/Info 6 0 R/Size 7>> startxref 620 %%EOF 

Saya perlu file yang akan dikeluarkan dengan konten pdf dan judul juga.

Semoga suntingan ini membantu sedikit ...

UPDATE (File dibuang sebagai respons dengan judul dan Konten BLOB):

Document document = new Document(PageSize.A4, 108, 72, 30, 72);
PdfWriter writer = PdfWriter.getInstance(document, outputstream);

document.open();

///-----Added Some Title----///

rs = stmt.executeQuery(queryToGetBLOBCONTENT);

if (rs.next()) {


response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=watermark.pdf");
oracle.sql.BLOB blob = (BLOB) rs.getBlob("MYPDF");
byte[] bytes = blob.getBytes(1, (int) blob.length());
InputStream is = blob.getBinaryStream();
PdfReader pdfReader = new PdfReader(is, bytes);
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
PdfImportedPage page;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
    if (pageOfCurrentReaderPDF > 0) {
        document.newPage();
    }
    pageOfCurrentReaderPDF++;
    currentPageNumber++;
    page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
    cb.addTemplate(page, 0, 0);
}
pageOfCurrentReaderPDF = 0;
outputstream.flush();
document.close();
outputstream.close();

}

Ini memberi saya sebuah file sebagai tanggapan yang memiliki BLOB dari DB dengan judul di atas dan itu dilakukan tanpa file fisik yang dihasilkan.

Sekarang untuk menghasilkan tanda air dan saya harus meneruskan dokumen ke PDfreader bagaimana saya bisa mencapai itu sebelum menutup dokumen (yaitu mengeksekusi document.close() , yang akan keluar menempatkan file tanpa tanda air saat aliran sungai ditutup)

Apa yang saya lakukan salah dalam kode ini? Bagaimana saya bisa mencapai file yang sama dengan tanda air dan itu juga tanpa file dibuat di latar belakang.


5
2018-03-28 06:21


asal


Jawaban:


Alih-alih menulis langsung ke servletOutputStream, Anda dapat mencoba pendekatan ini:

  1. Buat instance dari ByteArrayOutputStream
  2. Buat instance dokumen PDF "digabung". Yaitu. PDF form Blob + PDF yang memiliki judul. Contoh ini mungkin membantu: http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html
  3. Tulis PDF yang digabungkan ke instance dari ByteArrayOutputStream
  4. Setel panjang tanggapan konten
  5. Setel jenis konten dan disposisi konten
  6. Dapatkan byte dari ByteArrayOutputStream dan tuliskan byte tersebut ke servletOutputStream
  7. Tutup ByteArrayOutputStream

2
2018-03-29 12:51



Jika Anda tidak ingin membuat file sementara, maka Anda hanya perlu mendapatkan PDF sebagai InputStream dari DB dan biarkan iText membaca darinya dan akhirnya menulis ke OutputStream dari respon. Pertanyaan Anda sebenarnya terlalu luas untuk memberikan jawaban yang sesuai ("Saya tidak mendapatkan tempat" tidak memberikan banyak hal untuk dikerjakan), jadi inilah jawaban yang luas:

InputStream input = resultSet.getBinaryStream("columnname");
PdfReader reader = new PdfReader(input);
// ...

OutputStream output = response.getOutputStream();
PdfWriter pdfWriter = PdfWriter.getInstance(document, output);
// ...

Anda juga dapat menyebarkan sekitar ByteArrayOutputStream sebagai gantinya.


Memperbarui sesuai masalah Anda:

  1. Anda perlu mengatur header tanggapan sebelum Anda memberikan respons kepada badan PdfWriter.

    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
    PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
    // ...
    
  2. Singkirkan garis-garis berikut. Mereka hanya akan mengacaukan segalanya.

    byte[] bytes = blob.getBytes(1, (int) blob.length());
    servletOutputStream.write(bytes, 0, bytes.length);
    servletOutputStream.flush();
    servletOutputStream.close();
    

    Itu PdfWriter sudah akan menulis ke badan respon. Anda tidak perlu mengulanginya sendiri.


2
2018-03-28 13:16