package com.ruoyi.service.impl;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.ruoyi.domain.vo.PhotoStorageVO;
import com.ruoyi.service.PdfTemplateManagementService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.Map;

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

    /**
     * 检验报告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();
            }
        }
    }

    /**
     * 渲染数据
     * @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;
        }
    }

}