本文共 18246 字,大约阅读时间需要 60 分钟。
话不多说,直接贴代码吧。
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.lang.StringUtils;/** * 勾画圆形公司章 * * @author ldd */public class DrawSeal { //生成文件路径 public static final String FILE_PATH = "d:/"; private final static int WIDTH = 160; private final static int HEIGHT = 110; /** * 画圆形章 * @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; //创建缓存 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-10)/2, (HEIGHT-10)/6-3); //设置画笔宽度 gs.setStroke(new BasicStroke(3)); //画圆形边框 gs.drawOval(2, 2, WIDTH-4, HEIGHT-10); //设置字体 gs.setFont(new Font("宋体", Font.BOLD, 21));// 画数据(合同专用章) drawCenterMessage(gs, name1, WIDTH/2+2, (HEIGHT-10) * 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-10)/2, WIDTH/2-8, (HEIGHT-10)/2-8); //设置字体 gs.setFont(new Font("宋体", Font.BOLD, 9)); //画下方的环形数字 drawBelowNumber(gs, numCode, WIDTH/2, (HEIGHT-10)/2, WIDTH/2-8, (HEIGHT-10)/2+8); //释放此图形的上下文以及它使用的所有系统资源 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() + ".png"; out = new FileOutputStream(imgFile); ImageIO.write(bufImg, "png", 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 wr, int hr) { if (message != null) { // 根据输入字符串得到字符数组 String[] messages = 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 ascentY = - bounds.getY()-2; double ascentX = - bounds.getX()-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 = wr - ascentX; double x0 = CENTERX; double y0 = CENTERY - hr + ascentY; // 旋转角度 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 wr, int hr) { if (message != null) { // 根据输入字符串得到字符数组 String[] messages = 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) + 4; // 上坡度 double ascentY = -bounds.getY(); double ascentX = -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 = wr - ascentX; double x0 = CENTERX; double y0 = CENTERY - hr + ascentY; // 旋转角度 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); } public static void main(String[] args) { drawCircularChapter("国税局", "陕西XX有限公司", "A1002"); }}=========================================================== /** * 写入到pdf 公章处 */ private void drawSeal(){ //pdf模板所在路径 (通过类名获取文件路径) String templateFileName = DrawSeal2.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(); }
转载地址:http://pjqqd.baihongyu.com/