PdfTemplateManagementServiceImpl.java 10.5 KB
Newer Older
1 2
package com.ruoyi.service.impl;

3
import com.itextpdf.text.*;
4
import com.itextpdf.text.pdf.*;
5 6 7
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PdfBaseWriter;
import com.ruoyi.common.utils.StringUtils;
8
import com.ruoyi.domain.vo.PhotoStorageVO;
9
import com.ruoyi.domain.vo.ReviewEnterpriseArchiveViewVO;
10
import com.ruoyi.service.PdfTemplateManagementService;
11
import com.ruoyi.service.ReviewEnterpriseArchiveService;
12 13 14
import io.minio.MinioClient;
import io.minio.ObjectWriteArgs;
import io.minio.PutObjectArgs;
15
import org.springframework.beans.factory.annotation.Autowired;
16
import org.springframework.beans.factory.annotation.Value;
17 18 19 20
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
21
import java.io.ByteArrayInputStream;
22 23 24 25
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
26 27
import java.util.*;
import java.util.List;
28 29 30 31 32 33 34 35 36

/**
 * PDF模板管理Service业务层处理
 * @author gxk
 */
@Service
@Transactional
public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementService {

37 38 39 40 41 42 43 44 45 46 47 48
    @Value("${minio.bucketName}")
    private String bucketName;

    @Value("${minio.url}")
    private String minioEndpoint;

    @Value("${minio.accessKey}")
    private String accessKey;

    @Value("${minio.secretKey}")
    private String secretKey;

49 50 51
    @Autowired
    private ReviewEnterpriseArchiveService reviewEnterpriseArchiveService;

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
    /**
     * 检验报告PDF下载
     * @param response
     */
    @Override
    public void generateInspectionReport(HttpServletResponse response) throws Exception {
        PdfReader reader = null;
        PdfStamper ps = null;
        OutputStream fos = null;
        ByteArrayOutputStream bos = null;
        try {
            // 模板绝对路径--服务器
            String fileName = "/template/receipt_template_02_27.pdf";
            // 读取现有模板内容
            reader = new PdfReader(fileName);
            // 创建输出流
            bos = new ByteArrayOutputStream();
            // 实例化PdfStamper准备编辑pdf内容
            ps = new PdfStamper(reader, bos);

            // 获取表单所有元素
            AcroFields fields = ps.getAcroFields();

            // 设置具体字体格式的编码, 不设置的话中文可能不会显示
            BaseFont bf = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            fields.addSubstitutionFont(bf);

            // 渲染
//            fillData(fields, map, ps);
            renderData(fields);

            PhotoStorageVO photoStorageVO = new PhotoStorageVO();
            Class<? extends PhotoStorageVO> aClass = photoStorageVO.getClass();
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field field : declaredFields) {
                String name = field.getName();
                System.out.println(name);
            }

            //必须要调用这个,否则文档不会生成的
            ps.setFormFlattening(true);
            if(ps != null){
                ps.close();
            }
            //生成pdf路径存放的路径
            fos = response.getOutputStream();
            fos.write(bos.toByteArray());

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(fos!=null){
                fos.flush();
                fos.close();
            }
            if (bos != null){
                bos.close();
            }
            if(reader != null){
                reader.close();
            }
        }
    }

116 117
    /**
     * 企业留档文件PDF下载
118
     * @param taskId
119
     * @return
120
     * @throws Exception
121 122
     */
    @Override
123
    public String generateRetentionFile(Long taskId) throws Exception {
124 125 126 127 128 129 130 131
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // 新建
        PdfBaseWriter document = new PdfBaseWriter(outputStream);
        // 打开
        document.open();
        // 内容
        // 封面
        document.setParagraph("检验中心名称", 12f, 0, 60,15f, 120f);
132
        document.setParagraph("企业留档文件", 30f, Element.ALIGN_CENTER, 0,15f, 180f);
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
        PdfPTable customTable = new PdfPTable(new float[]{15, 50});
        customTable.setWidthPercentage(70);
        document.writeNoBorderCell("检验依据:", Element.ALIGN_LEFT, 1, 1, customTable);
        document.writeBottomCell("GB xxxx-xxxx 汽车整车信息安全技术要求", Element.ALIGN_LEFT, 1, 1, customTable);
        document.writeNoBorderCell("检验项目:", Element.ALIGN_LEFT, 1, 1, customTable);
        document.writeBottomCell("汽车信息安全管理要求、车辆信息安全一般要求、车辆信息安全技术要求", Element.ALIGN_LEFT, 1, 1, customTable);
        document.writeNoBorderCell("创建时间:", Element.ALIGN_LEFT, 1, 1, customTable);
        document.writeBottomCell("2024-07-01", Element.ALIGN_LEFT, 1, 1, customTable);
        document.writeNoBorderCell("委托单位名称:", Element.ALIGN_LEFT, 1, 1, customTable);
        document.writeBottomCell("xxxxxxxxxxxxxxxxxxx", Element.ALIGN_LEFT, 1, 1, customTable);
        document.addContent(customTable);
        document.setParagraph("检验中心名称", 20f, Element.ALIGN_CENTER, 0, 100f, 0f);
        // 下一页
        document.newPage();
        document.setParagraph("检验中心名称", 12f, 0, 30,15f, 20f);
        // 创建表格
        List<String> list = Arrays.asList("文件名称", "文件目录", "标准章节", "标准要求", "审查要点");
        float[] columnWidths = {20, 20, 20, 70, 70};
        PdfPTable table = document.createWithHeaderTable(list, columnWidths);
152 153 154 155 156 157 158 159 160 161 162
        // 查询数据
        List<ReviewEnterpriseArchiveViewVO> viewList = reviewEnterpriseArchiveService.view(taskId);
        for (ReviewEnterpriseArchiveViewVO view : viewList) {
            document.writeCell(view.getFileName(), Element.ALIGN_LEFT, 1, view.getItems().size(), table);
            view.getItems().forEach(item -> {
                document.writeCell(item.getCatalogue(), Element.ALIGN_LEFT, 1, 1, table);
                document.writeCell(item.getChapter(), Element.ALIGN_LEFT, 1, 1, table);
                document.writeCell(item.getStandard(), Element.ALIGN_LEFT, 1, 1, table);
                document.writeCell(item.getKeyPoint(), Element.ALIGN_LEFT, 1, 1, table);
            });
        }
163 164 165 166 167
        document.addContent(table);
        // 关闭
        document.close();

        // 上传到Minio
盖献康's avatar
盖献康 committed
168
        return uploadMinio(outputStream, "企业留档文件" + "_" + taskId);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
    }

    /**
     * 上传到minio
     * @param outputStream 输出流
     * @param fileName 文件名
     * @return minio存储地址
     */
    private String uploadMinio(ByteArrayOutputStream outputStream, String fileName) throws Exception {
        // 1.连接Minio
        MinioClient minioClient =MinioClient.builder()
                .endpoint(minioEndpoint)
                .credentials(accessKey, secretKey)
                .build();
        // 2.上传
        // 把os流转为is流
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        String newFileName = assemblyPdfName(fileName);
        PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(newFileName)
                .contentType("application/pdf")
                .stream(inputStream, inputStream.available(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build();
        minioClient.putObject(putObjectArgs);
        return newFileName;
    }

    /**
     * 拼接pdf文件名
     * @param name
     * @return
     */
    public String assemblyPdfName(String name) {
        return StringUtils.format("{}/{}.pdf", DateUtils.datePath(), name);
    }

205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
    /**
     * 渲染数据
     * @param fields
     */
    private void renderData(AcroFields fields) {

    }


    /**
     * 填充模板中的数据
     * @param fields
     * @param data 是一个Map<String,String> 主要存储 key 表单模板中的单元格名 value为想要赋的值,遍历
     * @param ps
     */
    public void fillData(AcroFields fields, Map<String, String> data, PdfStamper ps) {
        try {
            for (String key : data.keySet()) {
                String value = data.get(key);
                if (key.contains("image")) {
                    addImageToPdf(key, fields, ps, value);
                    continue;
                }
                // 为字段赋值,注意字段名称是区分大小写的
                fields.setField(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加图片
     * @param key 应为模板名
     * @param form 动态字段
     * @param stamper
     * @param filePath 本地图片路径
     * @throws DocumentException
     * @throws IOException
     * @throws IOException
     */
    private static void addImageToPdf(String key,AcroFields form, PdfStamper stamper, String filePath) throws DocumentException, IOException, IOException {

        // 通过图片域名获取所在页和坐标,左下角为起点
        int pageNo = form.getFieldPositions(key).get(0).page;
        Rectangle signRect = form.getFieldPositions(key).get(0).position;
        float x = signRect.getLeft();
        float y = signRect.getBottom();

        // 读图片
        Image image = Image.getInstance(filePath);
        // 获取操作的页面
        PdfContentByte under = stamper.getOverContent(pageNo);
        // 根据域的大小缩放图片
        image.scaleToFit(signRect.getWidth() * 2, signRect.getHeight());
        // 添加图片并设置位置(个人通过此设置使得图片垂直水平居中,可参考,具体情况已实际为准)
        image.setAbsolutePosition(x, y);
        under.addImage(image);
    }

    /**
     * 通过属性名获取属性在对象里的值
     * @param obj
     * @param propertyName
     * @return
     * @param <T>
     */
    public static <T> T getPropertyValue(Object obj, String propertyName) {
        try {
            // 获取对象的类
            Class<?> objClass = obj.getClass();

            // 获取类的指定属性
            Field field = objClass.getDeclaredField(propertyName);

            // 设置属性为可访问
            field.setAccessible(true);

            // 获取属性的值
            @SuppressWarnings("unchecked")
            T value = (T) field.get(obj);

            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}