Ruoyi-vue导出PDF

一. 后端代码

1.引入依赖
<!-- 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>
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;
  });
}

三. 测试结果

在这里插入图片描述

完结~

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: Ruoyi-vue-pro是一款便捷的前端Java框架,其官方开发指南PDF可在官网或相关技术博客上进行下载。 该开发指南PDF主要介绍了Ruoyi-vue-pro的框架结构、设计规范、使用方法等内容,为开发人员提供了全面的参考资料。在其中可以学习到如何使用IDE工具进行项目开发、如何对接后端API接口、如何进行代码打包和发布、如何进行项目调试等技巧。 此外,该开发指南PDF还提供了大量代码示例,方便开发人员更好地理解和掌握框架使用。同时,对于想要深度定制Ruoyi-vue-pro框架的开发者,该开发指南PDF也提供了一些扩展和集成方案,方便自定义组件和功能的实现。 总之,Ruoyi-vue-pro开发指南PDF是一份十分实用和详尽的前端框架开发指南,对于想要使用该框架开发项目的开发者来说是不可多得的学习资料。建议各位开发者在开始使用Ruoyi-vue-pro前,先进行该指南的学习,以便更好地开展项目工作。 ### 回答2: ruoyi-vue-pro 是一个开源的后台管理系统,采用前后端分离的开发架构,前端采用 Vue.js 框架开发,后台采用 SpringBoot 框架开发。ruoyi-vue-pro 开发指南 pdf 是一份详细的开发文档,其中包括了系统的功能介绍、搭建环境、项目结构、模块设计等内容。 在功能介绍中,文档详细介绍了系统的模块功能,包括登录管理、角色权限管理、用户管理、菜单管理、数据字典管理等。在搭建环境中,文档给出了详细的开发环境配置步骤,包括安装数据库、安装 Java JDK 等内容。在项目结构中,文档介绍了整个项目的文件结构,包括前后端代码的目录结构和各个文件的作用。 在模块设计中,文档详细说明了各个模块的设计思路、实现方式和交互流程。其中,登录管理模块通过 JWT 鉴权实现用户登录,角色权限管理模块通过 Shiro 实现用户权限控制,数据字典管理模块通过缓存技术实现字典数据的高效查询。文档还提供了详细的代码示例和开发注意事项,方便开发者自行开发新的模块。 总之,ruoyi-vue-pro 开发指南 pdf 是一份非常详细的开发文档,无论是已经使用过该系统的开发者,还是新手开发者都能够轻松地了解系统的架构特点和开发流程,快速上手进行开发工作。 ### 回答3: ruoyi-vue-pro 开发指南 pdf 是一本非常实用的指南手册,旨在帮助开发人员更好地理解和利用该开源项目。该指南详细介绍了 ruoyi-vue-pro 项目的核心功能和特点,以及如何在项目中运用这些功能来开发高效、易用的应用程序。 指南从项目的搭建和配置开始,包括项目依赖的环境、安装和配置开发工具的步骤,以及如何在项目中添加新的组件和插件等。接着,指南详细介绍了项目的各种功能和构架,包括如何使用路由、Vuex、Mock等功能来实现应用程序的交互和通信。 该指南在介绍每个功能和构架时,都提供了大量的代码示例和实用的技巧,使开发人员可以更加深入地了解和学习该项目的全部功能。此外,该指南还提供了一些常见问题的解答和调试技巧,帮助开发人员更加科学和高效地开发ruoyi-vue-pro项目。 总之,ruoyi-vue-pro 开发指南 pdf 是一本非常实用和详细的指南手册,对于希望学习和开发ruoyi-vue-pro项目的开发人员来说,是一本不可或缺的工具书。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值