- 导入依赖
<!-- pdf-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
- 编写工具类
PDFUtil
:
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
/**
* @Description: pdf工具类
*/
public class PDFUtil {
/**
* 生成文字段落
* @param content 渲染的文字内容
* @param font 字体
* @param alignment 设定段落的对齐方式,参数1为居中对齐、2为右对齐、3为左对齐,默认为左对齐。
* @return 返回文档段落
*/
public static Paragraph getParagraph (String content, Font font, Integer alignment){
Paragraph paragraph = new Paragraph(content,font) ;
if (alignment != null && alignment >= 0){
paragraph.setAlignment(alignment);
}
return paragraph ;
}
/**
* 生成图片段落
* @param imgPath 图片路径
* @param width 图片宽度
* @param height 图片高度
* @return 返回图片段落
* @throws Exception
*/
public static Image getImage (String imgPath, float width, float height) throws Exception {
Image image = Image.getInstance(imgPath);
image.setAlignment(Image.MIDDLE);
if (width > 0 && height > 0){
image.scaleAbsolute(width, height);
}
return image ;
}
/**
* 生成表格段落
* @param numColumns 表格列数
* @param totalWidth 表格宽度
* @return 返回表格段落
* @throws Exception
*/
public static PdfPTable getPdfPTable (int numColumns, float totalWidth) throws Exception {
// 表格处理
PdfPTable table = new PdfPTable(numColumns);
// 设置表格宽度比例为%100
table.setWidthPercentage(100);
// 设置宽度:宽度平均
table.setTotalWidth(totalWidth);
// 锁住宽度
table.setLockedWidth(true);
// 设置表格上面空白宽度
table.setSpacingBefore(10f);
// 设置表格下面空白宽度
table.setSpacingAfter(10f);
// 设置表格默认为无边框
table.getDefaultCell().setBorder(0);
table.setPaddingTop(50);
table.setSplitLate(false);
return table ;
}
/**
* 表格内容
*/
public static PdfPCell getPdfPCell (Phrase phrase){
return new PdfPCell (phrase) ;
}
/**
* 设置表格数据带样式
* @param dataTable 表格
* @param font 字体
* @param cellList 表格数据
*/
public static void addTableCell (PdfPTable dataTable, Font font, List<String> cellList){
for (String content:cellList) {
dataTable.addCell(getParagraph(content,font,-1));
}
}
/**
* 文件下载
* @param path
* @param response
*/
public static void downloadNet(String path, HttpServletResponse response) {
InputStream fis = null;
OutputStream out = null;
// path是指欲下载的文件的路径。
File file = new File(path);
// 取得文件名。
String fileName = file.getName();
System.out.println(fileName);
try {
fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
// 清空response
// response.reset();
out = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
//如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
out.write(buffer);
out.flush();
} catch (IOException ex) {
ex.getStackTrace();
} finally {
try {
File f = new File(path);
f.delete();
if (fis != null) {
fis.close();
}
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
- 编写业务类
CreatePDFService
:
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* @Description: 创建PDF测试类
*/
public class CreatePDFService {
/**
* PDF使用的字体,此处使用的是windos自带的字体
*/
private static String FONT = "C:\\Windows\\Fonts\\Simhei.ttf";
private static String PAGE_TITLE = "汽车租赁合同" ;
/**
* pdf标题样式
*/
private static Font TITLE_FONT = FontFactory.getFont(FONT, BaseFont.IDENTITY_H,20, Font.BOLD);
/**
* 标签样式,等同于 <h1>
*/
private static Font NODE_FONT = FontFactory.getFont(FONT, BaseFont.IDENTITY_H,15, Font.BOLD);
/**
* 标签样式,等同于 <h2>
*/
private static Font BLOCK_FONT = FontFactory.getFont(FONT, BaseFont.IDENTITY_H,13, Font.BOLD, BaseColor.BLACK);
/**
* 内容样式
*/
private static Font INFO_FONT = FontFactory.getFont(FONT, BaseFont.IDENTITY_H,12, Font.NORMAL,BaseColor.BLACK);
/**
* 表格文字样式
*/
private static Font CONTENT_FONT = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
/**
* 创建pdf
* @return
* @throws Exception
*/
public static String createPdfPage () throws Exception {
File path = new File(System.getProperty("java.io.tmpdir") + File.separator + "pdf");
if (path.mkdirs()) ;
String outPdfPath = path + File.separator + "测试.pdf";
// 创建文档
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outPdfPath));
document.open();
// 报告标题
document.add(PDFUtil.getParagraph(PAGE_TITLE,TITLE_FONT,1)) ;
document.add(PDFUtil.getParagraph("\n租赁人:张三",INFO_FONT,-1)) ;
document.add(PDFUtil.getParagraph("\n出租方:好车车汽车租赁有限公司\n\n",INFO_FONT,-1)) ;
// 报告内容
// 段落标题 + 报表图
document.add(PDFUtil.getParagraph("城市数据分布统计",NODE_FONT,-1)) ;
document.add(PDFUtil.getParagraph("\n· 可视化图表\n\n",BLOCK_FONT,-1)) ;
// 设置图片宽高
float documentWidth = document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin();
float documentHeight = documentWidth / 580 * 320;
document.add(PDFUtil.getImage("D:\\chat\\a.png",documentWidth-80,documentHeight-80)) ;
// 数据表格
document.add(PDFUtil.getParagraph("\n· 数据详情\n\n",BLOCK_FONT,-1)) ;
PdfPTable dataTable = PDFUtil.getPdfPTable(6,500) ;
// 设置表格
List<String> tableHeadList = tableHead () ;
List<List<String>> tableDataList = getTableData () ;
PDFUtil.addTableCell(dataTable,CONTENT_FONT,tableHeadList);
for (List<String> tableData : tableDataList) {
PDFUtil.addTableCell(dataTable,CONTENT_FONT,tableData);
}
document.add(dataTable);
document.add(PDFUtil.getParagraph("\n· 报表描述\n\n",BLOCK_FONT,-1)) ;
document.add(PDFUtil.getParagraph("数据报告可以监控每天的推广情况," +
"可以针对不同的数据表现进行分析,以提升推广效果。",CONTENT_FONT,-1)) ;
document.newPage() ;
document.close();
writer.close();
return outPdfPath;
}
/**
* 生成表格数据
* @return
*/
public static List<List<String>> getTableData (){
List<List<String>> tableDataList = new ArrayList<>() ;
for (int i = 0 ; i < 3 ; i++){
List<String> tableData = new ArrayList<>() ;
tableData.add("浙江"+i) ;
tableData.add("杭州"+i) ;
tableData.add("276"+i) ;
tableData.add("33.3%") ;
tableData.add("33.3%") ;
tableData.add("33.3%") ;
tableData.add("33.3%") ;
tableData.add("33.3%") ;
tableDataList.add(tableData) ;
}
return tableDataList ;
}
/**
* 创建表格标题
* @return
*/
public static List<String> tableHead (){
List<String> tableHeadList = new ArrayList<>() ;
tableHeadList.add("省份") ;
tableHeadList.add("城市") ;
tableHeadList.add("数量") ;
tableHeadList.add("百分比") ;
tableHeadList.add("百分比") ;
tableHeadList.add("百分比") ;
tableHeadList.add("百分比2") ;
tableHeadList.add("百分比1") ;
return tableHeadList ;
}
}
注:以上文件地址,及图片地址需要替换为自己的目录
- 编写接口
TestController
:
import com.example.demo.util.CreatePDFService;
import com.example.demo.util.PDFUtil;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@RestController
@RequestMapping("/api")
public class TestController {
/**
* 导出PDF
* @param response
* @throws FileNotFoundException
*/
@PostMapping("/exportPdf")
public void goetPdf(HttpServletResponse response) throws FileNotFoundException {
String path = null;
try {
path = CreatePDFService.createPdfPage();
} catch (Exception e) {
e.printStackTrace();
}
PDFUtil.downloadNet(path, response);
}
}
- Vue调用接口及接收文件流
export default {
data() {
return {
}
},
methods: {
//导出pdf文件,此处的exportPdf是请求接口/api/exportPdf的方法,此处直接替换为axios代码请求即可
//后端返回的是文件流
exportPdf(orderParam).then(res => {
if (res) {
let fileName= "测试"
this.downloadFile(res,fileName, "pdf");
}
});
},
//下载pdf
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
const fileName = name + '.' + suffix;
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
},
},
- 请求结果
响应文件流 - PDF下载效果