我需要在内存中创建iTextPDF文档文件后将其转换为byte[]。我已经测试过我正确创建PDF没有问题。问题是如何将其转换为字节数组以存储在DB中。
这是我的代码:
Document generatedDocument = reportService.generateRequestForm(scdUser, jsonObject, 0, null);
reportService.generateRequestForm(scdUser, jsonObject, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter pdfWriter = PdfWriter.getInstance(generatedDocument, baos);
generatedDocument.open();
document.setDocument(baos.toByteArray()); // stores as blob
我在数据库blob列得到null值。
这是我的文档域对象:
文档域对象
@Entity
@Table(name = "document")
public class Document implements java.io.Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "document_id", nullable = false)
private int documentId;
@Column(name = "document_name", nullable = false, length = 65535)
private String documentName;
@Column(name = "document_type", nullable = false)
private int documentType;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "upload_date", nullable = false, length = 19)
private Date uploadDate = new Date();
@Column(name = "document", nullable = false)
private byte[] document; // BLOB COLUMN
@Column(name = "document_size", nullable = false)
private long documentSize;
@Column(name = "title", nullable = true, insertable = true, updatable = true, length = 65535, precision = 0)
private String title;
@Column(name = "tag", nullable = true, insertable = true, updatable = true, length = 65535, precision = 0)
private String tag;
@Column(name = "description", nullable = true, insertable = true, updatable = true, length = 65535, precision = 0)
private String description;
@Column(name = "shared", nullable = false, insertable = true, updatable = true, length = 1, precision = 0)
private boolean shared = false;
@Column(name = "status", nullable = false)
private int status = DocumentStatus.READY.getStatus();
public int getDocumentId() {
return this.documentId;
}
public void setDocumentId(int documentId) {
this.documentId = documentId;
}
public String getDocumentName() {
return this.documentName;
}
public void setDocumentName(String documentName) {
this.documentName = documentName;
}
public int getDocumentType() {
return this.documentType;
}
public void setDocumentType(int documentType) {
this.documentType = documentType;
}
public Date getUploadDate() {
return this.uploadDate;
}
public void setUploadDate(Date uploadDate) {
this.uploadDate = uploadDate;
}
public byte[] getDocument() {
return this.document;
}
public void setDocument(byte[] document) {
this.document = document;
}
public long getDocumentSize() {
return this.documentSize;
}
public void setDocumentSize(long documentSize) {
this.documentSize = documentSize;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean getShared() {
return shared;
}
public void setShared(boolean shared) {
this.shared = shared;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
我有一个类似的问题…我会创建文档,在我创建它的类中,我可以将它保存到文件中,它工作得很好。但是,当我尝试将其作为流返回时,我会得到一个空值。
问题是一旦文档被关闭(文档。关闭()),它也会关闭流。
解决方法是在我创建文档时创建一个ByteArrayOutputStream,并将PdfWriter输出到它。然后,我可以对PDF字节做任何我想做的事情…在我的例子中,我将它们转换为StreamedContent发送给用户。
创建一个变量来保存字节:
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
让PdfWriter在创建文档时将数据输出到byte[]:
Document document = new Document(PageSize.LETTER, 0.75F, 0.75F, 0.75F, 0.75F);
PdfWriter.getInstance(document, byteArrayOutputStream); // Do this BEFORE document.open()
document.open();
createPDF(document); // Whatever function that you use to create your PDF
document.close();
完成生成PDF后,只需获取字节并随意处理它们。
byte[] pdfBytes = byteArrayOutputStream.toByteArray();
我不知道您的reportService类是什么样子,但这可能是一个放置它的好地方。
希望这有帮助。
只是更新iText 7版本的答案。
private static byte[] createPDF() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
PdfDocument pdfDocument = new PdfDocument(writer);
Document document = new Document(pdfDocument);
//Write the file content
document.close();
return byteArrayOutputStream.toByteArray();
}
从注释来看,它似乎与运行时生成PDF的方式无关,而是与存储在DB中的方式有关。您还需要提供该代码。
以下是我实际拥有的(我的测试):
持有人:
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class PDFHolder implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(columnDefinition = "LONGBLOB")
private byte[] documentPDF;
public byte[] getDocumentPDF() {
return documentPDF;
}
public void setDocumentPDF(byte[] documentPDF) {
this.documentPDF = documentPDF;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
存储库,它执行保存:
@Repository
public interface PDFHolderRepository extends JpaRepository<PDFHolder, Long> {}
和实际插入:
private void generateDatabaseRows() {
try{
String urlPDF = "http://cetatenie.just.ro/LinkClick.aspx?fileticket=K13DZkoIE2o%3d&tabid=57&mid=593";
URL url = new URL(urlPDF);
ByteBuffer byteBufferResponse = this.getAsByteArray(url.openConnection());
byte [] responseArray = byteBufferResponse.array();
System.out.println("Size of the PDF : " + responseArray.length);
// Save it to DB
PDFHolder pdfHolder = new PDFHolder();
pdfHolder.setDocumentPDF(responseArray);
pdfHolderRepository.save(pdfHolder);
} catch(Exception e){
e.printStackTrace();
}
}
private ByteBuffer getAsByteArray(final URLConnection urlConnection) throws IOException {
final ByteArrayOutputStream tmpOut = new ByteArrayOutputStream();
final InputStream inputStream = urlConnection.getInputStream();
final byte[] buf = new byte[1024];
int len;
while (true) {
len = inputStream.read(buf);
if (len == -1) {
break;
}
tmpOut.write(buf, 0, len);
}
tmpOut.close();
return ByteBuffer.wrap(tmpOut.toByteArray(), 0, tmpOut.size());
}
当然,我在这个类中有一个@Autow的存储库:
@Autowired
PDFHolderRepository pdfHolderRepository;