JAVA导出PDF借助 iText
pom先引入两个jar包
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itextpdf.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>${asian.version}</version>
</dependency>
导出逻辑(这里是生成很多pdf文件,然后压缩到一个文件里面)
@SneakyThrows
@Override
public ResponseEntity<InputStreamResource> exportTradeAckPdfFile(QueryTradeAckDetailReqDto queryTradeAckDetailDto){
FileOutputStream fileOutputStream = null;
PdfWriter writer=null;
File pdfFile=null;
Document tradeAckPdfDocument=null;
List<File> files = new ArrayList<>();
InputStreamResource inputStreamResource=null;
String zipFilePath=null;
//定义压缩文件名
String zipFileName="交易确认单"+ DateUtils.getDateyyyyMMdd()+".zip";
try{
QueryTradeAckDetailReqBo reqBo= AcctUserInfoReq.Req.getReqBo(queryTradeAckDetailDto);
//获取筛选条件内所有客户交易账号
List<QueryCustNoRespBo> queryCustNoRespBoList= sAcktradeblotterMapper.queryCustNoListByChannelCode(reqBo);
//每一条记录生成一个PDF文件,然后保存到本地
for (QueryCustNoRespBo custNoRespBo:queryCustNoRespBoList) {
QueryAccountUserTradeAckDetailReqBo queryAccountUserTradeAckDetailReqBo=new QueryAccountUserTradeAckDetailReqBo();
queryAccountUserTradeAckDetailReqBo.setAckStartDate(reqBo.getAckStartDate());
queryAccountUserTradeAckDetailReqBo.setAckEndDate(reqBo.getAckEndDate());
queryAccountUserTradeAckDetailReqBo.setChannelCodes(reqBo.getChannelCodes());
queryAccountUserTradeAckDetailReqBo.setCustNo(custNoRespBo.getCustNo());
//单个客户信息
QueryAccountUserInfoRespBo queryAccountUserInfoRespBo=sAcktradeblotterMapper.queryAccountUserInfo(custNoRespBo.getCustNo());
tradeAckPdfDocument=new Document();
//pdfFile=new File(pathProperties.getFilePath());
zipFilePath=pathProperties.getFilePath()+"/"+zipFileName;
pdfFile=new File(pathProperties.getFilePath()+"/"+queryAccountUserInfoRespBo.getInvName()+custNoRespBo.getCustNo()+".pdf");
//输出文件到服务器本地
fileOutputStream = new FileOutputStream(pdfFile);
writer = PdfWriter.getInstance(tradeAckPdfDocument, fileOutputStream);
writer.setViewerPreferences(PdfWriter.PageModeUseThumbs);
tradeAckPdfDocument.setPageSize(PageSize.A4);
tradeAckPdfDocument.open();
tradeAckPdfDocument.add(getPdfTitleParagraph("交易对账单"));
//客户交易详情
List<QueryAccountUserTradeDetailRespBo> queryAccountUserTradeDetailRespBoList=sAcktradeblotterMapper.queryAccountUserTradeDetail(queryAccountUserTradeAckDetailReqBo);
tradeAckPdfDocument=addAccountUserTradeDetailToDocument(queryAccountUserTradeDetailRespBoList,tradeAckPdfDocument,reqBo);
Paragraph titleParagraph = new Paragraph(" 风险提示", getPdfTableTitleFont());
tradeAckPdfDocument.add(titleParagraph);
Paragraph firstParagraph = new Paragraph(" 在线自助交易单据服务仅供客户查询及打印参考使用,不得伪造、篡改。投资者在本机构持有的基金份额及交易确", getPdfRowCellFont());
tradeAckPdfDocument.add(firstParagraph);
Paragraph secendParagraph = new Paragraph(" 认结果以注册登记机构最终确认的结果为准。", getPdfRowCellFont());
tradeAckPdfDocument.add(secendParagraph);
Paragraph fourthParagraph = new Paragraph(" 快协助您解决。", getPdfRowCellFont());
tradeAckPdfDocument.add(fourthParagraph);
files.add(pdfFile);
if(tradeAckPdfDocument.isOpen()){
tradeAckPdfDocument.close();
}
writer.close();
fileOutputStream.close();
}
//文件夹压缩
inputStreamResource=addFileToZipPackage(files,zipFilePath);
}catch (Exception e) {
log.error("导出交易确认PDF表出错",e);
}finally {
return ResponseEntity.ok()
.header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,"FileName",HttpHeaders.CONTENT_DISPOSITION)
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment;filename=" + zipFileName)
.header("FileName", zipFileName)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(inputStreamResource);
}
}
//为PDF文件绘制内容明细
private Document addAccountUserTradeDetailToDocument(List<QueryAccountUserTradeDetailRespBo> queryAccountUserTradeDetailRespBoList, Document document,QueryTradeAckDetailReqBo reqBo){
try{
document.add(getPdfTableTitleParagraph(" 交易明细("+reqBo.getAckStartDate()+"-"+reqBo.getAckEndDate()+"申请数据明细)"));
final List<String> acctUserInfoTradeDetailColumns =
Collections.unmodifiableList( Arrays.asList( new String[]
{"确认日期","基金名称","基金代码","业务类型","申请金额(元)","申请份额(份)","确认金额(元)","确认份额(份)","确认净值","手续费 (元)"} ) ) ;
PdfPTable pdfTable =getPdfTable(10,496);
for (String cellValue:acctUserInfoTradeDetailColumns) {
pdfTable.addCell(getPdfHeadCell(cellValue));
}
for (QueryAccountUserTradeDetailRespBo rowValue:queryAccountUserTradeDetailRespBoList) {
pdfTable.addCell(getPdfCell(rowValue.getAckDate()));
pdfTable.addCell(getPdfCell(rowValue.getFundName()));
pdfTable.addCell(getPdfCell(rowValue.getFundCode()));
pdfTable.addCell(getPdfCell(rowValue.getApkType()));
pdfTable.addCell(getPdfCenterCell(rowValue.getAppAmt()));
pdfTable.addCell(getPdfCenterCell(rowValue.getAppBalance()));
pdfTable.addCell(getPdfCenterCell(rowValue.getAckAmt()));
pdfTable.addCell(getPdfCenterCell(rowValue.getAckBalance()));
pdfTable.addCell(getPdfCenterCell(rowValue.getAckNav()));
pdfTable.addCell(getPdfCenterCell(rowValue.getFee()));
}
document.add(pdfTable);
}
catch (Exception e){
log.error("导出交易确认PDF表附加交易详情出错",e);
}finally {
return document;
}
}
public static PdfPTable getPdfTable(int rowSize, int tableRowLength) throws Exception {
float[] rowWidths=new float[rowSize];
for(int i=0;i<rowSize;i++){
rowWidths[i]=1f;
}
PdfPTable pdfTable = new PdfPTable(rowWidths);
pdfTable.setLockedWidth(true);
pdfTable.setTotalWidth(tableRowLength);
pdfTable.setSpacingBefore(10); // 前间距
pdfTable.setSpacingAfter(10); // 后间距
return pdfTable;
}
声明字体和创建一个列
public static Font getPdfRowCellFont() throws Exception {
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H",
BaseFont.NOT_EMBEDDED);
Font fontChinese = new Font(bfChinese, 10, Font.NORMAL);
return fontChinese;
}
public static Paragraph getPdfTableTitleParagraph(String tableTitle) throws Exception {
Paragraph titleParagraph=new Paragraph(tableTitle,getPdfTableTitleFont());
titleParagraph.setAlignment(Element.ALIGN_LEFT);
titleParagraph.setSpacingAfter(10f);
titleParagraph.setSpacingBefore(10f);
return titleParagraph;
}
public static Font getPdfTableTitleFont() throws Exception {
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H",
BaseFont.NOT_EMBEDDED);
Font fontChinese = new Font(bfChinese, 14, Font.BOLD);
return fontChinese;
}
public static Paragraph getPdfTitleParagraph(String pdfTitle) throws Exception {
Paragraph titleParagraph=new Paragraph(pdfTitle,getPdfTitleFont());
titleParagraph.setAlignment(Element.ALIGN_CENTER);
titleParagraph.setSpacingAfter(10f);
titleParagraph.setSpacingBefore(10f);
return titleParagraph;
}
public static Font getPdfTitleFont() throws Exception {
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H",
BaseFont.NOT_EMBEDDED);
Font fontChinese = new Font(bfChinese, 18, Font.BOLD);
return fontChinese;
}
public static PdfPCell getPdfCell(String cellValue) throws Exception {
PdfPCell pdfCell = new PdfPCell();
Paragraph paragraph = new Paragraph(cellValue, getPdfRowCellFont());
pdfCell.setMinimumHeight(30);//设置表格行高
pdfCell.setUseAscender(true);
pdfCell.setVerticalAlignment(pdfCell.ALIGN_MIDDLE);
pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfCell.setPhrase(paragraph);
return pdfCell;
}
public static PdfPCell getPdfCenterCell(String cellValue) throws Exception {
PdfPCell pdfCell = new PdfPCell();
pdfCell.setMinimumHeight(30);//设置表格行高
Paragraph paragraph = new Paragraph(cellValue, getPdfRowCellFont());
pdfCell.setUseAscender(true);
pdfCell.setVerticalAlignment(pdfCell.ALIGN_MIDDLE);
pdfCell.setVerticalAlignment(Element.ALIGN_CENTER);
pdfCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
pdfCell.setPhrase(paragraph);
return pdfCell;
}
public static PdfPCell getPdfHeadCell(String cellValue) throws Exception {
PdfPCell pdfCell = new PdfPCell();
pdfCell.setMinimumHeight(30);//设置表格行高
pdfCell.setUseAscender(true);
pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfCell.setVerticalAlignment(pdfCell.ALIGN_MIDDLE);
Paragraph paragraph = new Paragraph(cellValue, getPdfRowCellFont());
pdfCell.setPhrase(paragraph);
return pdfCell;
}
压缩文件
private InputStreamResource addFileToZipPackage(List<File> pdfFile,String zipFilePath) throws IOException {
ZipOutputStream zipOutputStream=null;
FileInputStream fileInputStream=null;
InputStreamResource resource=null;
File zipFile=new File(zipFilePath);
if(zipFile.exists()){
zipFile.delete();
}else {
zipFile.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
zipOutputStream = new ZipOutputStream(fileOutputStream);
for(File file:pdfFile){
byte[] buf = new byte[BUFFER_SIZE];
zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
int len;
fileInputStream = new FileInputStream(file);
while ((len = fileInputStream.read(buf)) != -1) {
zipOutputStream.write(buf, 0, len);
}
fileInputStream.close();
file.delete();
}
zipOutputStream.close();
//从服务器读取文件 流传给前端
fileInputStream = new FileInputStream(zipFile) ;
resource = new InputStreamResource(fileInputStream);
fileOutputStream.close();
return resource;
}