Ruoyi-vue导出PDF

一. 后端代码

1.引入依赖


<dependency>
    <groupId>com.itextpdfgroupId>
    <artifactId>itextpdfartifactId>
    <version>${itextpdf.version}version>
dependency>

<dependency>
    <groupId>com.itextpdfgroupId>
    <artifactId>itext-asianartifactId>
    <version>${itext.asian.version}version>
dependency>

2. 业务代码

  • 工具类
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;
  });
}

三. 测试结果

Ruoyi-vue导出PDF_第1张图片

完结~

你可能感兴趣的:(vue.js,spring,boot,java)