第一种写法,使用org.apache.tools.zip,具体流程:
1、逐个生成pdf文件
2、打包zip
3、下载第二种写法,使用java.util.zip,这种写法没成功。
1、使用pdf文件流进行打包
2、下载
这里介绍第一种。
一、导入相应的依赖包
<!--itext pdf-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!--ant zip-->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.12</version>
</dependency>
二、生成pdf 和 zip 文件
PdfUtil.java
关键代码
/**
* 创建document对象
*/
public static Document createDocument() {
//生成pdf
Document document = new Document();
// 页面大小
Rectangle rectangle = new Rectangle(PageSize.A4);
// 页面背景颜色
rectangle.setBackgroundColor(BaseColor.WHITE);
document.setPageSize(rectangle);
// 页边距 左,右,上,下
document.setMargins(20, 20, 20, 20);
return document;
}
/**
* @param text 段落内容
* @return
*/
public static Paragraph createParagraph(String text, Font font) {
Paragraph elements = new Paragraph(text, font);
elements.setSpacingBefore(5);
elements.setSpacingAfter(5);
elements.setSpacingAfter(spacing);
return elements;
}
/**
* 创建默认列宽,指定列数、水平(居中、右、左)的表格
*
* @param colNumber
* @param align
* @return
*/
public static PdfPTable createTable(int colNumber, int align) {
PdfPTable table = new PdfPTable(colNumber);
try {
table.setTotalWidth(maxWidth);
table.setLockedWidth(true);
table.setHorizontalAlignment(align);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并)
*
* @param value
* @param font
* @param align
* @param colspan
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
cell.setMinimumHeight(20f);
return cell;
}
业务代码
/**
* 生成单个pdf文件,并返回文件对象
* @param dto 需要生成pdf的数据对象
* @return UploadResult 自定义文件对象
*/
private UploadResult generatePDF(ActivityApplyLogDto dto) {
Document document = null;
try {
document = PdfUtil.createDocument();
// 这里是返回一个pdf的存放地址和文件名,可自定义,如下
// UploadResult rs = new UploadResult();
// rs.setPath(filePath);
// rs.setName(fileName);
UploadResult fileUploadResult = fileService.getFilePath("pdf");
FileOutputStream fos = new FileOutputStream(fileUploadResult.getPath());
PdfWriter.getInstance(document, fos);
document.open();
// 字体定义
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font titlefont = new Font(bfChinese, 16, Font.BOLD);
Font textfont = new Font(bfChinese, 10, Font.NORMAL);
// 生成居中标题
Paragraph title = PdfUtil.createParagraph("活动报名信息\n", titlefont);
title.setAlignment(Element.ALIGN_CENTER);
document.add(title);
document.add(new Paragraph(" "));
PdfPTable table = PdfUtil.createTable(6, Element.ALIGN_CENTER);
BizUser user = dto.getUser();
BizActivity activity = dto.getActivity();
table.addCell(PdfUtil.createCell("关联活动名称", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(activity.getName(), textfont, Element.ALIGN_LEFT, 2));
table.addCell(PdfUtil.createCell("姓名", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(user.getName(), textfont, Element.ALIGN_LEFT, 2));
table.addCell(PdfUtil.createCell("手机号码", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(user.getPhone(), textfont, Element.ALIGN_LEFT, 2));
table.addCell(PdfUtil.createCell("性别", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(user.getGender(), textfont, Element.ALIGN_LEFT, 2));
table.addCell(PdfUtil.createCell("证件类型", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(user.getCardType(), textfont, Element.ALIGN_LEFT, 2));
table.addCell(PdfUtil.createCell("证件号码", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(user.getCardNum(), textfont, Element.ALIGN_LEFT, 2));
table.addCell(PdfUtil.createCell("报名状态", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(dto.getStatus(), textfont, Element.ALIGN_LEFT, 2));
table.addCell(PdfUtil.createCell("报名时间", textfont, Element.ALIGN_LEFT, 1));
table.addCell(PdfUtil.createCell(dto.getApplyTime(), textfont, Element.ALIGN_LEFT, 2));
document.add(table);
return fileUploadResult;
}catch (Exception e) {
throw new BadRequestException("生成失败");
} finally {
if (document != null) document.close();
}
}
生成 zip 文件ZipUtil.java
关键代码,参考了https://www.cnblogs.com/alphajuns/p/12442315.html
的写法
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
public class ZipUtil {
public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator;
/**
* 这里先不关闭流,否则会报异常
* @param zip 压缩目的地址
* @param srcFiles 压缩的源文件
*/
public static String zipFile(String zip, List<File> srcFiles) throws Exception{
String path = SYS_TEM_DIR + zip;
FileOutputStream fos = new FileOutputStream(path);
ZipOutputStream out = new ZipOutputStream(fos);
out.setEncoding("GBK");
for (File _f : srcFiles) {
handlerFile(out, _f);
}
return path;
}
/**
* 处理压缩
* @param out 目标文件流
* @param srcFile 源文件信息
*/
private static void handlerFile(ZipOutputStream out, File srcFile) throws IOException {
InputStream in = new FileInputStream(srcFile);
out.putNextEntry(new ZipEntry(srcFile.getName()));
int len = 0;
byte[] _byte = new byte[1024];
while ((len = in.read(_byte)) > 0) {
out.write(_byte, 0, len);
}
in.close();
out.closeEntry();
}
}
三、下载
后台代码
public void downloadPDF(List<BizActivityApplyLogDto> all, HttpServletResponse response) throws Exception {
List<File> fileList = new ArrayList<>();
for (BizActivityApplyLogDto dto : all) {
UploadResult rs = generatePDF(dto);
fileList.add(new File(rs.getPath()));
}
//zip压缩包名称
String zipFileName = "活动报名信息.zip";
response.setCharacterEncoding("UTF-8");
response.setContentType("application/octet-stream");
String path = ZipUtil.zipFile(zipFileName, fileList);
FileInputStream fileInputStream = new FileInputStream(path);
//设置Http响应头告诉浏览器下载文件名 Filename
response.setHeader("Content-Disposition", "attachment;Filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
OutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[2048];
int len = 0;
while ((len = fileInputStream.read(bytes)) > 0) {
outputStream.write(bytes, 0, len);
}
outputStream.flush();
fileInputStream.close();
outputStream.close();
}
前端代码
//点击导出按钮
<el-button type="primary" icon="el-icon-download" size="mini" :loading="exportLoading" @click="downloadPDF">导出PDF</el-button>
downloadPDF(){
let total = this.page.total
if (total == null || total == undefined || parseInt(total) <= 0) {
this.$alert('没有数据可导出')
}
this.$confirm('确定导出结果列表中的'+ total +'个pdf文件吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.exportLoading = true
download(this.baseUrl + '/downloadPDF', this.getParams()).then(res => {
downloadFile(res, this.title + '数据', 'zip')
this.exportLoading = false
}).catch(()=>{
this.exportLoading = true
})
})
}
// download 使用了axios 和 qs,
export function download(url, params) {
return request({
url: url + '?' + qs.stringify(params, {
indices: false }),
method: 'get',
responseType: 'blob'
})
}
// 下载文件
export function downloadFile(obj, name, suffix) {
const url = window.URL.createObjectURL(new Blob([obj]))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
const fileName = parseTime(new Date()) + '-' + name + '.' + suffix
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}