引入依赖
<!-- pdf工具 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itextpdf.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>${itext.asian.version}</version>
</dependency>
工具类
package com.ruoyi.common.utils.file;
import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.ruoyi.project.gas.domain.Alarm;
import com.ruoyi.project.gas.domain.Instance;
import org.springframework.core.io.ClassPathResource;
public class PdfUtils {
/**
* 告警对象
* @param alarm
* @return
*/
public static PdfPTable createAlarmPdfTable(Alarm alarm) throws Exception{
//添加中文字体
//BaseFont bfChinese=BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
BaseFont baseFont = BaseFont.createFont(new ClassPathResource("/static/ttf/SourceHanSansCN-Normal.ttf").getPath(),
BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
//设置字体样式
Font labelFont = new Font(baseFont,11, Font.NORMAL);
labelFont.setColor(182, 156, 181);
Font font = new Font(baseFont,11, Font.NORMAL);
// 创建两列表格
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100);
// 设置每列的列宽
float[] columnWidths = {30f, 70f};
table.setWidths(columnWidths);
table.addCell(getCell("仪表名称:", labelFont));
table.addCell(getCell(alarm.getMeterName(), font));
table.addCell(getCell("告警类型:", labelFont));
table.addCell(getCell(alarm.getEventType(), font));
table.addCell(getCell("告警发生时间:", labelFont));
table.addCell(getCell(DateUtil.formatDateTime(alarm.getCreateTime()), font));
table.addCell(getCell("告警解除时间:", labelFont));
table.addCell(getCell(DateUtil.formatDateTime(alarm.getEndTime()), font));
table.addCell(getCell("告警持续时长:", labelFont));
table.addCell(getCell(alarm.getKeepTime(), font));
return table;
}
public static PdfPCell getCell(String text) {
Paragraph elements = new Paragraph(20, text);
PdfPCell pdfPCell = new PdfPCell(elements);
pdfPCell.setMinimumHeight(30);
pdfPCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
pdfPCell.setHorizontalAlignment(Element.ALIGN_CENTER);
return pdfPCell;
}
public static PdfPCell getCell(String text, Font font) {
Paragraph elements = new Paragraph(text, font);
PdfPCell pdfPCell = new PdfPCell(elements);
pdfPCell.setBorder(0);
// pdfPCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
//pdfPCell.setHorizontalAlignment(Element.ALIGN_CENTER);
//pdfPCell.setLeading(2, 1);
return pdfPCell;
}
}
service
@Override
public void createAlarmPDF(HttpServletResponse response, List<Alarm> alarms) throws Exception{
//设置纸张规格为A4纸
Rectangle rect = new Rectangle(PageSize.A4);
//创建文档实例
Document document = new Document(rect);
OutputStream out = response.getOutputStream();
PdfWriter.getInstance(document,out);
document.open();
document.newPage();
//添加中文字体
//BaseFont bfChinese=BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
BaseFont baseFont = BaseFont.createFont(new ClassPathResource("/static/ttf/SourceHanSansCN-Normal.ttf").getPath(),
BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
//设置字体样式
Font font = new Font(baseFont,11, Font.NORMAL); //正常
//添加内容
document.add(new Paragraph("HD content here"));
// 图片网络地址
String netUrl = configService.selectConfigByKey("alarm_image_url");
// 图片本地地址
String localUrl = configService.selectConfigByKey("alarm_image_local");
for (int i = 0; i < alarms.size(); i++) {
Alarm alarm = alarms.get(i);
PdfPTable tableDesc = PdfUtils.createAlarmPdfTable(alarm);
// 2列的表表格
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100); // 宽度100%填充
table.setSpacingBefore(10f); // 前间距
//table.setSpacingAfter(10f); // 后间距
// 设置每列的宽度,因为是定义了三列的表格,所以这里的设置3个数据,代表了每列的宽度
float[] columnWidths = { 100f, 100f};
table.setWidths(columnWidths);
ArrayList<PdfPRow> rows = table.getRows();
// 单元格数组
PdfPCell[] cells = new PdfPCell[2];
PdfPRow pdfPRow1 = new PdfPRow(cells);
//document.add(new Paragraph("imager"));
// 获取图片
Image image = null;
try {
image = Image.getInstance(((localUrl == null || localUrl.trim().length() == 0) ? netUrl : localUrl)
+ alarm.getImgUrl());
} catch (Exception e) {
log.error("导出pdf报错,获取图片错误~", e);
ClassPathResource classPathResource = new ClassPathResource("/static/images/empty.png");
InputStream inputStream =classPathResource.getInputStream();
int fileLength = (int) classPathResource.getFile().length();
byte b[] = new byte[fileLength];
inputStream.read(b);
inputStream.close();
image = Image.getInstance(b);
}
//设置图片的宽度和高度
image.scaleAbsolute(200, 200);
//单元格
cells[0] = new PdfPCell();//单元格内容
//cells[0].setBorderColor(BaseColor.BLUE); //设置边框颜色
//cells[0].setPaddingLeft(20); //左填充20
cells[0].setHorizontalAlignment(Element.ALIGN_CENTER); //水平居中
cells[0].setVerticalAlignment(Element.ALIGN_MIDDLE); //垂直居中
cells[0].setImage(image);
cells[1] = new PdfPCell(tableDesc);
// 第一行的内容
rows.add(pdfPRow1);
document.add(table);
}
//关闭文档
document.close();
}
Controller
@GetMapping("/exportPDF")
@PreAuthorize("@ss.hasPermi('gas:alarm:exportPDF')")
public void exportPDF(AlarmReq alarmReq, HttpServletResponse response) throws Exception{
// 获取当前的用户
LoginUser loginUser = SecurityUtils.getLoginUser();
//设置响应格式等
response.setContentType("application/pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
//设置要导出的pdf的标题
String title = LocalDate.now().toString();
response.setHeader("Content-disposition","attachment; filename=".concat(String.valueOf(URLEncoder.encode(title + ".pdf", "UTF-8"))));
List<Alarm> list = alarmService.findAlarmList(alarmReq);
if (list != null && list.size() > 1000) {
list = list.subList(0, 1000);
}
alarmService.createAlarmPDF(response, list);
}
前端代码
api.js
注意: responseType:‘blob’ 必须添加,否则导出会报错.
import request from '@/utils/request'
export function exportAlarmPDF(query) {
//以文件流的方式返回数据
return request({
url: '/gas/alarm/exportPDF',
method: 'get',
responseType:'blob',
params: query
})
}
Vue组件
<el-button
type="warning" plain
icon="el-icon-download"
:loading="download"
size="mini"
@click="exportPDF"
v-hasPermi="['gas:alarm:exportPDF']"
> 导出PDF </el-button>
// 引入api
import { exportAlarmPDF } from "@/api/gas/pdf";
// 导出事件方法
exportPDF(){
this.download = true;
exportAlarmPDF(this.queryParams).then((res)=>{
//导出文件名
var filename = new Date().getTime();
//创建url
let url = window.URL.createObjectURL(res)
//创建a标签 并设置属性
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', filename + '.pdf')
//添加a标签
document.body.appendChild(link)
//执行下载
link.click();
//释放url对象
URL.revokeObjectURL(link.href);
//释放a标签
document.body.removeChild(link);
this.download = false;
});
}