zoukankan      html  css  js  c++  java
  • 生成一个签章(用java.awt画一个签章) 并添加到pdf 公章处

    生成一个签章(用java.awt画一个签章) 并添加到pdf 公章处
    package com.bjpowernode.p2p.admin.util;

    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Polygon;
    import java.awt.font.FontRenderContext;
    import java.awt.geom.AffineTransform;
    import java.awt.geom.Rectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Calendar;
    import java.util.UUID;

    import javax.imageio.ImageIO;

    import org.apache.commons.lang3.StringUtils;

    import com.bjpowernode.p2p.admin.config.SystemConfig;

    /**
     * 勾画圆形公司章
     *
     * @author ldd
     */
    public class DrawSeal {
        //生成文件路径
        public static final String FILE_PATH = SystemConfig.getConfigProperty("seal_img_path");
        
        private final static int WIDTH = 160;
        
        private final static int HEIGHT = 160;
        
        /**
         * 画圆形章
         * @param name1 章的名字
         * @param name2 公司的名字
         * @param numCode 公司的数字编码
         * @param width
         * @param height
         * @return
         */
        public static String drawCircularChapter(String name1, String name2, String numCode){
            OutputStream out = null;
            InputStream in = null;
            byte[] data = null;
            //创建缓存
            BufferedImage bufImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            //获得画布
            Graphics2D gs = bufImg.createGraphics();
            //设置颜色
            gs.setColor(Color.WHITE);
            //填充区域
            gs.fillRect(0, 0, WIDTH, HEIGHT);
            //设置画笔颜色
            gs.setColor(new Color(204,41,41));
            //画五角星
            drawFiveStar(gs, WIDTH/2, HEIGHT/2, HEIGHT/6-3);
            //设置画笔宽度
            gs.setStroke(new BasicStroke(3));
            //画圆形边框
            gs.drawOval(2, 2, WIDTH-4, HEIGHT-4);
            //设置字体
            gs.setFont(new Font("宋体", Font.BOLD, 21));
            //画数据(合同专用章)
            drawCenterMessage(gs, name1, WIDTH/2+2, HEIGHT * 4 / 5);
            if (StringUtils.isNotEmpty(name2) && name2.length()>11) {
                int len = name2.length();
                int fontSize = 18;
                switch (len) {
                case 12:
                    fontSize = 20;
                    break;
                case 13:
                    fontSize = 19;
                    break;
                case 14:
                    fontSize = 19;
                    break;
                case 15:
                    fontSize = 18;
                    break;
                case 16:
                    fontSize = 17;
                    break;
                case 17:
                    fontSize = 16;
                    break;
                case 18:
                    fontSize = 15;
                    break;
                case 19:
                    fontSize = 14;
                    break;
                case 20:
                    fontSize = 14;
                    break;
                case 21:
                    fontSize = 12;
                    break;
                case 22:
                    fontSize = 12;
                    break;
                case 23:
                    fontSize = 10;
                    break;
                case 24:
                    fontSize = 10;
                    break;
                case 25:
                    fontSize = 9;
                    break;
                default :
                    fontSize = 18;
                    break;
                }
                //设置字体
                gs.setFont(new Font("宋体", Font.PLAIN, fontSize));
            }
            //画上方的环形字
            drawUpperMessage(gs, name2, WIDTH/2, HEIGHT/2, WIDTH/2-10);
            //设置字体
            gs.setFont(new Font("宋体", Font.BOLD, 9));
            //画下方的环形数字
            drawBelowNumber(gs, numCode, WIDTH/2, HEIGHT/2, HEIGHT/2);
            //释放此图形的上下文以及它使用的所有系统资源
            gs.dispose();
            //输出图片
            try {
                StringBuffer fileDir = new StringBuffer();
                fileDir.append(Calendar.getInstance().get(Calendar.YEAR)).append(File.separator).append(Calendar.getInstance().get(Calendar.MONTH)+1).append(File.separator).append(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)).append(File.separator);
                File ff = new File(FILE_PATH + fileDir.toString());
                if (!ff.exists()) {
                    ff.mkdirs();
                }
                String imgFile = FILE_PATH + fileDir.toString() + UUID.randomUUID() + ".bmp";
                out = new FileOutputStream(imgFile);
                ImageIO.write(bufImg, "bmp", out);
                
                bufImg.flush();
                out.flush();
                
                /*in = new FileInputStream(imgFile);
                data = new byte[in.available()];
                in.read(data);*/
                
                //对字节数组Base64编码
                /*sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
                //返回Base64编码过的字节数组字符串
                String encodeStr = encoder.encode(data);
                //将图片文件删除
                File file = new File(imgFile);
                if (file.isFile()) {
                    file.delete();
                }*/
                return imgFile;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (null != out) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (null != in) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }
        
        public static void drawCenterMessage(Graphics2D gs, String message, int CENTERX, int CENTERY){
            if (message != null) {
                // 根据输入字符串得到字符数组
                String[] messages2 = message.split("", 0);
                String[] messages = new String[messages2.length];
                System.arraycopy(messages2, 0, messages, 0, messages2.length);
                // 输入的字数
                int ilength = messages.length;
                Font f = gs.getFont();
                FontRenderContext context = gs.getFontRenderContext();
                Rectangle2D bounds = f.getStringBounds(message, context);
                // 字符宽度=字符串长度/字符数
                double char_interval = (bounds.getWidth() / ilength) - 1;
                
                int first = 0, second = 0;
                boolean odd = false;
                if (ilength % 2 == 1) {
                    first = (ilength - 1) / 2;
                    odd = true;
                } else {
                    first = (ilength) / 2 - 1;
                    second = (ilength) / 2;
                    odd = false;
                }
                if (odd) {
                    gs.drawString(messages[first],
                            (float)(CENTERX - char_interval / 2 - char_interval / 10),
                            (float) CENTERY);
                    // 中心点的右边
                    for (int i = first + 1; i < ilength; i++) {
                        double x = CENTERX + (i - first - 0.6) * char_interval;
                        gs.drawString(messages[i],(float) x,
                                (float) CENTERY);
                    }
                    // 中心点的左边
                    for (int i = first - 1; i > -1; i--) {
                        double x = CENTERX - (first - i + 0.6) * char_interval;
                        gs.drawString(messages[i],(float) x,
                                (float) CENTERY);
                    }
                } else {
                    // 中心点的右边
                    for (int i = second; i < ilength; i++) {
                        double x = CENTERX + (i - second - 0.1) * char_interval;
                        gs.drawString(messages[i],(float) x,
                                (float) CENTERY);
                    }
                    // 中心点的左边
                    for (int i = first; i > -1; i--) {
                        double x = CENTERX - (first + 1 - i + 0.1) * char_interval;
                        gs.drawString(messages[i],(float) x,
                                (float) CENTERY);
                    }
        
                }
            }
        }
        
        /**
         * 画上方圆弧的汉字
         *
         * @param gs
         * @param message
         * @param CENTERX
         * @param CENTERY
         * @param r
         */
        public static void drawUpperMessage(Graphics2D gs, String message, int CENTERX, int CENTERY, int r) {
            if (message != null) {
                // 根据输入字符串得到字符数组
                String[] messages2 = message.split("", 0);
                String[] messages = new String[messages2.length];
                System.arraycopy(messages2, 0, messages, 0, messages2.length);
                // 输入的字数
                int ilength = messages.length;
                Font f = gs.getFont();
                FontRenderContext context = gs.getFontRenderContext();
                Rectangle2D bounds = f.getStringBounds(message, context);
                // 字符宽度=字符串长度/字符数
                double char_interval = (bounds.getWidth() / ilength) - 1;
                // 上坡度
                double ascent = -bounds.getY()-2;
                int first = 0, second = 0;
                boolean odd = false;
                if (ilength % 2 == 1) {
                    first = (ilength - 1) / 2;
                    odd = true;
                } else {
                    first = (ilength) / 2 - 1;
                    second = (ilength) / 2;
                    odd = false;
                }
                double r2 = r - ascent;
                double x0 = CENTERX;
                double y0 = CENTERY - r + ascent;
                // 旋转角度
                double a = 2 * Math.asin(char_interval / (2 * r2));
        
                if (odd) {
                    gs.drawString(messages[first],(float)(x0 - char_interval / 2), (float) y0);
                    // 中心点的右边
                    for (int i = first + 1; i < ilength; i++) {
                        double aa = (i - first) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],(float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                                (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                    }
                    // 中心点的左边
                    for (int i = first - 1; i > -1; i--) {
                        double aa = (first - i) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(-aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],
                        (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                        (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
                    }
                } else {
                    // 中心点的右边
                    for (int i = second; i < ilength; i++) {
                        double aa = (i - second + 0.3) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],
                            (float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                            (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                    }
                    // 中心点的左边
                    for (int i = first; i > -1; i--) {
                        double aa = (first - i + 0.7) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(-aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],
                            (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                            (float) (y0 + ay + char_interval / 2* Math.sin(aa)));
                    }
                }
            }
        }
        
        /**
         * 画下方圆弧数字编码
         *
         * @param gs
         * @param message
         * @param CENTERX
         * @param CENTERY
         * @param r
         */
        public static void drawBelowNumber(Graphics2D gs, String message, int CENTERX, int CENTERY, int r) {
            if (message != null) {
                // 根据输入字符串得到字符数组
                String[] messages2 = message.split("", 0);
                String[] messages = new String[messages2.length - 1];
                System.arraycopy(messages2, 1, messages, 0, messages2.length - 1);
                // 输入的字数
                int ilength = messages.length;
                Font f = gs.getFont();
                FontRenderContext context = gs.getFontRenderContext();
                Rectangle2D bounds = f.getStringBounds(message, context);
                // 字符宽度=字符串长度/字符数
                double char_interval = (bounds.getWidth() / ilength) + 4;
                // 上坡度
                double ascent = -bounds.getY();
                int first = 0, second = 0;
                boolean odd = false;
                if (ilength % 2 == 1) {
                    first = (ilength - 1) / 2;
                    odd = true;
                } else {
                    first = (ilength) / 2 - 1;
                    second = (ilength) / 2;
                    odd = false;
                }
                double r2 = r - ascent;
                double x0 = CENTERX;
                double y0 = CENTERY - r + ascent;
                // 旋转角度
                double a = 2 * Math.asin(char_interval / (2 * r2));
                if (odd) {
                    // 中心点的右边
                    for (int i = first + 1; i < ilength; i++) {
                        double aa = (i - first + 0.5) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI - aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],
                            (float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                            2*CENTERY - (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                    }
                    // 中心点的左边
                    for (int i = first; i > -1; i--) {
                        double aa = (first - i - 0.5) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI + aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],
                            (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                            2*CENTERY - (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
                    }
                } else {
                    // 中心点的右边
                    for (int i = second; i < ilength; i++) {
                        double aa = (i - second + 1) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI - aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],
                            (float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                            2*CENTERY - (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                    }
                    // 中心点的左边
                    for (int i = first; i > -1; i--) {
                        double aa = (first - i) * a;
                        double ax = r2 * Math.sin(aa);
                        double ay = r2 - r2 * Math.cos(aa);
                        AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI + aa);
                        Font f2 = f.deriveFont(transform);
                        gs.setFont(f2);
                        gs.drawString(messages[i],
                            (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                            2*CENTERY - (float) (y0 + ay + char_interval / 2* Math.sin(aa)));
                    }
                }
            }
        }
        
        /**
         * 画章中间的五角星
         *
         * @param g
         * @param x
         * @param y
         * @param r
         */
        public static void drawFiveStar(Graphics g, int x, int y, int r) {
            double ch=72*Math.PI/180;
            int x1=x,
                x2=(int)(x-Math.sin(ch)*r),
                x3=(int)(x+Math.sin(ch)*r),
                x4=(int)(x-Math.sin(ch/2)*r),
                x5=(int)(x+Math.sin(ch/2)*r);
            int y1=y-r,
                y2=(int)(y-Math.cos(ch)*r),
                y3=y2,
                y4=(int)(y+Math.cos(ch/2)*r),
                y5=y4;
            int bx=(int)(x+Math.cos(ch)*Math.tan(ch/2)*r);
            int by=y2;

            Polygon a=new Polygon();
            Polygon b=new Polygon();
            a.addPoint(x2,y2);
            a.addPoint(x5,y5);
            a.addPoint(bx,by);
            b.addPoint(x1,y1);
            b.addPoint(bx,by);
            b.addPoint(x3,y3);
            b.addPoint(x4,y4);

            g.fillPolygon(a);
            g.fillPolygon(b);
        }
    }

    -----------------------------------------华丽的分割线  如果你需要以上操作 直接复制粘贴即可------------------------------------------------------------------------

    //写入到pdf 公章处
                //pdf模板所在路径 (通过类名获取文件路径)
                String templateFileName = ContractServiceImpl.class.getClassLoader().getResource("sb_loan_contract_borrow.pdf").getFile();
                //使用itext的包读取pdf模板
                PdfReader pdfReader = new PdfReader(templateFileName);
                
                // 提取pdf中的表单输入域字段
                AcroFields form = pdfStamper.getAcroFields();
                // 通过域名获取所在页(页数)和坐标,左下角为起点
                int pageNo = form.getFieldPositions("Chapter").get(0).page;
                Rectangle signRect = form.getFieldPositions("Chapter").get(0).position;
                //获取x y 坐标
                float x = signRect.getLeft();
                float y = signRect.getBottom();

                //生成一个签章(用java.awt 画一个章)  章:上需要几个常量值Constants.CHAPTER_NAME, Constants.CHAPTER_COMPANY_NAME, Constants.CHAPTER_SOCIAL_NUMBER
                String imgPath = DrawSeal.drawCircularChapter(Constants.CHAPTER_NAME, Constants.CHAPTER_COMPANY_NAME, Constants.CHAPTER_SOCIAL_NUMBER);
                
                // 读图片
                Image image = Image.getInstance(imgPath);
                // 获取操作的页面
                PdfContentByte under = pdfStamper.getOverContent(pageNo);
                // 根据域的大小缩放图片
                image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                // 添加图片
                image.setAbsolutePosition(x, y);
                under.addImage(image);
        
                pdfStamper.flush();
                pdfStamper.close();
                pdfReader.close();



  • 相关阅读:
    SQLAlchemy
    Redis
    Django框架详解
    nginx负载均衡(反向代理)
    Python 字典 fromkeys()方法
    docker容器的使用
    keepalived原理
    学习区块链必读的6本书
    MATLAB基础入门笔记
    思念是一种美丽的孤独
  • 原文地址:https://www.cnblogs.com/liudongdong666666/p/7811523.html
Copyright © 2011-2022 走看看