一个蛋疼的需求,蛋疼 的完成。。。Graphics2D 绘图,求改进!

客户要搞什么,通知公告,什么格式啊,分页啊,全都要用java绘图制作,超蛋疼。因为时间有点急,只是单纯实现他所说的去了,写的不好 ,求批斗,求提高,求意见,直接上代码啦。
package com.ztenc.oa.proj.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.xml.crypto.Data;

import org.eclipse.emf.ecore.InternalEObject.EStore;
import org.jgroups.demos.Chat;

import com.sun.corba.se.spi.orb.StringPair;
import com.sun.corba.se.spi.orbutil.fsm.Guard.Result;

/**
 * 文字写入图层背景工具类
 * 
 * 内容过多自动分页
 * 
 * 落款自动写入格式
 * 
 * @author fule
 */
public class ImageWUtil {

	// 常量字体大小
	public final static int LARGESIZE = 100; // 大字体
	public final static int NORMALSIZE = 50; // 普通字体
	public final static int SMALLSIZE = 30; // 小字体
	// 段间距
	public final static int SECTSIZE = 80;
	// 文字区边距
	public final static int PADDING = 100;
	public final static Color DEAUFT_COLOR = Color.WHITE;

	// 连续书写时的记录位
	int pointIndex;

	// title书写之后的记录位
	int pointOnTitle;

	// 当前第几页
	int indexPage = 1;

	Map<Integer, String> map;

	/**
	 * 设置当前书写的像素位子
	 * 
	 * @return
	 */
	private int setPointIndex(int increment) {
		pointIndex += increment;
		return pointIndex;
	}

	/**
	 * 内容区字体大小
	 */
	private int contentFontSize = NORMALSIZE;

	/**
	 * 标题字体大小
	 */
	private int titleFontSize = LARGESIZE;

	/**
	 * 段间距
	 */
	private int secttSize = SECTSIZE;

	/**
	 * 文本域边距大小
	 */
	private int contentPadding = PADDING;

	/**
	 * 画笔颜色
	 */

	private Color color;

	/**
	 * 背景图片
	 */
	private File bgFile;

	/**
	 * 设置背景图
	 * 
	 * @param bgFile
	 */
	public void setBgFile(File bgFile) {
		this.bgFile = bgFile;
	}

	/**
	 * 设置画笔颜色 默认白色
	 * 
	 * @param color
	 */
	public void setColor(Color color) {
		this.color = color;
	}

	/**
	 * 设置内容区字体大小 默认NORMALSIZE = 50
	 */
	public void setContentFontSize(int contentFontSize) {
		this.contentFontSize = contentFontSize;
	}

	/**
	 * 设置标题字体大小 默认LARGESIZE = 100
	 */
	public void setTitleFontSize(int titleFontSize) {
		this.titleFontSize = titleFontSize;
	}

	/**
	 * 设置段间距 默认SECTSIZE = 70
	 * 
	 * @param secttSize
	 */
	public void setSecttSize(int secttSize) {
		this.secttSize = secttSize;
	}

	/**
	 * 设置文本边距 默认PADDING70
	 * 
	 * @param contentPadding
	 */
	public void setContentPadding(int contentPadding) {
		this.contentPadding = contentPadding;
	}

	/**
	 * 合成图片 title 标题 testContext 段落
	 * 分页产生的图片名
	 * 递增1  
	 * @return
	 * @throws Exception
	 */

	public int compound(String strTitleString, String context,
			String[] luokuan) throws Exception {
		int resultCount=0;//生成的图片张数
		BufferedImage bi = null;
		try {
			bi = ImageIO.read(bgFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
		int imgWidth = bi.getWidth();
		int ImgHeight = bi.getHeight();
		Graphics2D g = getGraphics(bi);
		Font titleFont = new Font("微软雅黑", Font.PLAIN, titleFontSize);// 标题
		Font contentFont = new Font("微软雅黑", Font.PLAIN, contentFontSize);// 内容
		Font luoKuanFont = new Font("微软雅黑", Font.PLAIN, contentFontSize);// 落款
		if (strTitleString == null && context == null && luokuan == null) {
			throw new Exception("没有数据,没有写入任何数据");
		} else {
			g.setFont(contentFont);
			Map<Integer, String> pagemap = getPageStrings(imgWidth, ImgHeight,
					strTitleString, context);
			resultCount = pagemap.size();
			for (int i = 1; i <= resultCount; i++) {
				pointIndex = 0;// 初始化
				String pageContent = pagemap.get(i);
				if (strTitleString != null) {
					drawTitle(titleFont, imgWidth, strTitleString, g);
				}
				String[] testContext = getContents(pageContent);// 每一页段数据
				if (testContext != null) {
					for (int j = 0; j < testContext.length; j++) {
						drawContent(imgWidth, testContext[j], g);
					}
					if (pagemap.size() == 1 || i == pagemap.size()) {
						setPointIndex(2 * secttSize);// 设置落款 开始位置
						if (luokuan != null) {
							drawLuoKuan(imgWidth, luokuan, luoKuanFont, g);
						}
					}
				}
				try {
					String fatherPath = bgFile.getParent();
					String fileAbName = bgFile.getName();
					String fn = fileAbName.substring(0,fileAbName.lastIndexOf("."));//文件名前缀
					String filenameString = fatherPath+"/"+fn + i + ".jpg";
					File f = new File(filenameString);
					ImageIO.write(bi, "jpg", f);
					bi = ImageIO.read(bgFile);
					g = getGraphics(bi);
					g.setFont(contentFont);
				} catch (IOException e) {
					e.printStackTrace();
					return 0;
				}
			}
			g.dispose();
			bgFile.delete();//删除背景
			System.out.println("合成完毕");
			return resultCount;
		}

	}//end

	private Graphics2D getGraphics(BufferedImage bi) {
		Graphics2D g = bi.createGraphics();
		// 字体平滑
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(color);
		return g;
	}

	/**
	 * 写入标题 居中 字数过多换行
	 * 
	 * @param width
	 * @param title
	 * @param g
	 */
	public void drawTitle(Font font, int width, String title, Graphics2D g) {
		AttributedString as = null;
		title = ToSBC(title);
		int fullLen = (width - contentPadding * 2) / titleFontSize;// 一行的最多容量
		int titleLen = title.length();
		if (titleLen > fullLen) {
			String s = title;
			int writeLen = (s.length() + fullLen - 1) / fullLen;// 可写入行数
			String string;
			int sum = 0;
			for (int i = 0; i < writeLen - 1; i++) {
				int begin = i * fullLen;
				int end = begin + fullLen;
				string = s.substring(begin, end);// TODO
				int sl = string.length();// 实际每行写入字数
				as = new AttributedString(string);
				as.addAttribute(TextAttribute.FONT, font);
				g.drawString(as.getIterator(), width / 2 - sl / 2
						* titleFontSize, pointIndex
						+ (titleFontSize + secttSize / 2) * (i + 1));// i+1
																		// 去除二段重行
			}
			string = s.substring((writeLen - 1) * fullLen);
			as = new AttributedString(string);
			as.addAttribute(TextAttribute.FONT, font);
			g.drawString(as.getIterator(), width / 2 - string.length() / 2
					* titleFontSize, pointIndex
					+ (titleFontSize + secttSize / 2) * writeLen);// 最后一行
			sum += (titleFontSize + secttSize) * writeLen;
			setPointIndex(sum);
		} else {
			as = new AttributedString(title);
			as.addAttribute(TextAttribute.FONT, font);
			g.drawString(as.getIterator(), width / 2 - titleLen / 2
					* titleFontSize, setPointIndex(titleFontSize + secttSize));

		}
		pointOnTitle = pointIndex;
	}

	/**
	 * 写入落款
	 * 
	 * 从后面往前写
	 * 
	 * @param width
	 * @param wsString
	 *            内容
	 * @param g
	 * @throws Exception
	 */
	public void drawLuoKuan(int width, String[] wsString, Font font,
			Graphics2D g) throws Exception {
		AttributedString as = null;
		int padding = 2;
		int fontsize = font.getSize();
		int fullLen = (width - contentPadding * 2) / fontsize;// 一行的最多容量
		for (int i = 0; i < wsString.length; i++) {
			wsString[i] = ToSBC(wsString[i]);
			if (wsString[i].length() > fullLen) {
				throw new Exception("落款长度过长");
			}
			as = new AttributedString(wsString[i]);
			as.addAttribute(TextAttribute.FONT, font);
			if (wsString[0].length() > wsString[1].length()) {
				if (i == 0) {
					g.drawString(as.getIterator(),
							(fullLen - wsString[0].length() + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
					setPointIndex(-(secttSize / 2));
				} else {
					g.drawString(
							as.getIterator(),
							(fullLen
									- wsString[1].length()
									+ ((wsString[1].length() - wsString[0]
											.length()) / 2) + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
				}
			} else if (wsString[0].length() < wsString[1].length()) {
				if (i == 0) {
					g.drawString(
							as.getIterator(),
							(fullLen
									- wsString[0].length()
									+ ((wsString[0].length() - wsString[1]
											.length()) / 2) + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
					setPointIndex(-(secttSize / 2));
				} else {
					g.drawString(as.getIterator(),
							(fullLen - wsString[1].length() + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
				}
			}else {
				g.drawString(as.getIterator(),
						(fullLen - wsString[0].length() + padding)
								* fontsize, setPointIndex(fontsize
								+ secttSize));
				setPointIndex(-(secttSize / 2));
			}
		}

	}

	/**
	 * 文本边距为1个字符,首行缩进2个字符
	 * 
	 * 写入段落 内容区 一个字的像素为SMALLSIZE
	 * 
	 * @param width
	 *            图片宽度
	 * @param height
	 *            图片高度
	 * @param content
	 * @param g
	 */
	public void drawContent(int width, String content, Graphics2D g) {
		content = ToSBC(content);
		int fullFontLen = (width - contentPadding * 2) / contentFontSize;// 满行写入
																			// 可写长度(字数)
		String duanshou;
		int writeLen;
		int sum = 0;
		if (content.length() < fullFontLen - 2) {
			duanshou = content;
			writeLen = 1;
			g.drawString(duanshou, contentPadding + 2 * contentFontSize,
					setPointIndex(2 * secttSize));
		} else {
			duanshou = content.substring(0, fullFontLen - 2);// 段首 缩进两个字
			writeLen = (content.substring(duanshou.length() + 1).length()
					+ fullFontLen - 1)
					/ fullFontLen; // 可写入行数 不含段首行

			// 写入段首 段的开始 2*secttSize 段分割行
			g.drawString(duanshou, contentPadding + 2 * contentFontSize,
					setPointIndex(2 * secttSize));
			// 除去段首的内容区
			String str = content.substring(duanshou.length());
			// 写入内容
			String string;
			for (int i = 0; i < writeLen - 1; i++) {
				int begin = i * fullFontLen;
				int end = begin + fullFontLen;
				string = str.substring(begin, end);// TODO
				g.drawString(string, contentPadding, pointIndex + secttSize
						+ secttSize * i);
			}
			string = str.substring((writeLen - 1) * fullFontLen);
			g.drawString(string, contentPadding, pointIndex + secttSize
					+ secttSize * (writeLen - 1));// 最后一行d
			sum += ((secttSize) * (writeLen));// 段落之间的间隙
			setPointIndex(sum);
		}

	}

	/**
	 * 是否存在下一页
	 * 
	 * @param point
	 * @param height
	 * @return
	 */
	public boolean hasNextPage(int height) {
		if (pointIndex > (height - 2 * secttSize)) {
			// 存在下一页新页开始
			pointIndex = 0;
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 写入内容时是否产生分页 TODO 第一段就超出页 除第一段之后的超页
	 * 
	 * @param height
	 *            高度
	 * @param width
	 *            宽度
	 * @param testContext
	 * @return map<页码,内容>
	 */
	private Map<Integer, String> getPageStrings(int width, int height,
			String title, String testContext) {
		title = ToSBC(title);
		int titleFullLen = (width - contentPadding * 2) / titleFontSize;// 一行标题的最多容量
		int titleWriteLen = (title.length() + titleFullLen - 1) / titleFullLen;// 标题占有行
		int titleHeight = titleWriteLen * (titleFontSize + secttSize);// 标题高度

		int fullFontLen = (width - contentPadding * 2) / contentFontSize;// 满行写入可写长度(字数)

		int contentHeight = getDuanLuoHeight(fullFontLen, titleHeight, height,
				testContext);

		// int contentHeight = getContents(testContext).length * 2 *
		// secttSize;// 满区内容段落间距总高度

		int bgTotalRows = (height - titleHeight - contentHeight) / secttSize
				- 3;// 除去落款,背景可书写总行数

		int vTotalRows = (testContext.length() + fullFontLen - 1) / fullFontLen;// 实际内容所需行数

		// TDOD
		int fullWord = bgTotalRows * fullFontLen;// 满屏写入内容字数
		if (map == null) {
			map = new HashMap<Integer, String>();
		}
		if (vTotalRows < bgTotalRows) {
			map.put(indexPage, testContext);
		} else {
			int count = 0;

			int pageCount = (vTotalRows + bgTotalRows - 1) / bgTotalRows;// 需要总页数
			String string;
			for (int i = count; i < pageCount; i++) {
				if (i == pageCount - 1) {
					string = testContext.substring(i * fullWord);// 最后一页
				} else {
					string = testContext.substring(i * fullWord, (i + 1)
							* fullWord);
				}
				// System.out.println("当页内容:\n"+string);
				map.put(indexPage, string);
				indexPage++;

			}
		}
		System.out.println("总页数" + map.size());
		return map;
	}

	// 每页段落总间隙
	// 如果是第一页 写入 如果是其他的 算满屏额
	private int getDuanLuoHeight(int fullFontLen, int titleHeight, int height,
			String testContext) {
		int bgTotalRows = (height - titleHeight) / secttSize - 4;// 满页可写入行数
		int fullWord = bgTotalRows * fullFontLen;// 满屏写入内容字数
		int wlen = testContext.length();
		if (wlen < fullWord) {
			return getContents(testContext).length * 2 * secttSize;
		} else {
			return getContents(testContext.substring(0, fullWord)).length * 2
					* secttSize;
		}
	}

	/**
	 * 字符串处理
	 */
	private String[] getContents(String str) {
		while (str.startsWith("\r\n")) {
			str = str.substring(2);
		}
		String[] a = str.split("\\s{1,}");
		return a.length == 0 ? null : a;
	}

	/**
	 * 字符串处理
	 * 
	 * @param str
	 * @return
	 * @deprecated
	 */
	private String[] getContent(String str) {

		String string = str.replace("\r\n", "");
		string = string.replace("<p>", "{");
		string = string.replace("</p>", "}");
		List<String> list = new ArrayList<String>();
		while (string.indexOf("{") > -1) {
			int start = string.indexOf("{") + 1;
			int end = string.indexOf("}");
			String st = string.substring(start, end);
			list.add(st);
			string = string.substring(end + 1);
		}
		for (int i = 0; i < list.size(); i++) {
			if ("".equals(list.get(i)) || list.get(i) == null) {
				list.remove(i);
			}
		}
		String[] a = list.toArray(new String[0]);
		return a.length == 0 ? null : a;
	}

	// 半角转全角:
	public static String ToSBC(String input) {
		char[] c = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == 32) {
				c[i] = (char) 12288;
				continue;
			}
			if (c[i] < 127)
				c[i] = (char) (c[i] + 65248);
		}
		return new String(c);
	}

	
	public static char conversionNum(int c){
		char rc = 0;
		switch (c) {
			case 1: rc='一';
				break;
			case 2:rc='二';
				break;
			case 3:rc='三';
				break;
			case 4:rc='四';
				break;
			case 5:rc='五';
				break;
			case 6:rc='六';
				break;
			case 7:rc='七';
				break;
			case 8:rc='八';
				break;
			case 9:rc='九';
				break;
			case 10:rc='十';
			break;
			case 0:rc='〇';
		}
		return rc;
	}
	
	//解析月/日
	public static String conversionMouth(int a){
		if (a<=10) {
			return String.valueOf(conversionNum(a));
		}else {
			int gw=a%10;
			int sw=a/10;
			String swString = String.valueOf(conversionNum(sw));
			String gwString = String.valueOf(conversionNum(gw));
			if (a<20) {
				return "十"+gwString;
			}else {
				return swString+"十"+gwString;
			}
		}
	}
	
	//首零的处理
	public String removeBeginZ(String str){
		if (str.startsWith("0")) {
			int index = str.indexOf("0");
			return str.substring(index);
		}else {
			return str;
		}
		
	}
	
	/**
	 * 转化为中文日期格式
	 * 形式如:二〇一〇年十月二十一
	 * 转入格式:yyyy-MM-dd
	 * @param str
	 * @return 中文日期格式
	 * @throws Exception 
	 */
	public static String toCN_Date(String str) throws Exception{
		String eL = "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}";//匹配正则
		Pattern p = Pattern.compile(eL);
		Matcher m = p.matcher(str);
		boolean dateFlag = m.matches();
		if (dateFlag) {
			String[] strings = str.split("-");
			char[] y = strings[0].toCharArray();//年
			StringBuffer cndate = new StringBuffer();
			for (int i = 0; i < y.length; i++) {
				char cy =conversionNum((int)y[i]-48);
				cndate.append(cy);
			}
				String mounth = conversionMouth(Integer.parseInt(String.valueOf(strings[1])));
				String daString = conversionMouth(Integer.parseInt(String.valueOf(strings[2])));
				cndate.append("年"+mounth+"月");
				cndate.append(daString+"日");
			return cndate.toString();
		}else {
			throw new Exception("请使用正确格式的日期字符串");
		}
	}
	
	/**
	 * @param args
	 * @throws Exception 
	 * 
	 */

	public static void main(String[] args) throws Exception {
	/*	
		ImageWUtil iUtil = new ImageWUtil();
		try {
			System.out.println(iUtil.toCN_Date("2012-12-22"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		iUtil.setBgFile(new File("D:/testbook/bg.jpg"));
		iUtil.setColor(Color.WHITE);
		iUtil.setTitleFontSize(60);
		iUtil.setContentFontSize(45);
		iUtil.setContentPadding(70);
		iUtil.setSecttSize(70);
		String d = "";
		FileInputStream fInputStream = new FileInputStream(new File(
				"D:/testbook/testbook.txt"));
		byte[] by2 = new byte[5 * 1024];

		int temp = fInputStream.read(by2);

		d = new String(by2, 0, temp);

		// System.out.println(d);
		fInputStream.close();
		String t = "编程改革";
		String lk1 = "卡卡卡办公厅发";
		String lk2 = "二零一二年世界的风行 谨在此";
		try {
			iUtil.compound(t, d, new String[] { lk1, lk2 });
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		 String
		  test="\r\n\r\n\r\n\r\n\r\nasasa\r\n\r\nsasa\r\n\r\nsdasda\r\n\r\n";
		 String s[] =iUtil.getContents(test); System.out.println(s.length);
		 for (String string : s) { System.out.println(string); }
		 */
	}

}



分割线
================================================================
后面改进了下,解决一行中字母数字干扰行字数的问题,一行容量整齐了些,以及一些更多的一些设置。








import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.xml.crypto.Data;

import org.eclipse.emf.ecore.InternalEObject.EStore;
import org.jgroups.demos.Chat;

import com.sun.corba.se.spi.orb.StringPair;
import com.sun.corba.se.spi.orbutil.fsm.Guard.Result;
import com.ztenc.oa.proj.json.JSONArray;
import com.ztenc.oa.proj.json.JSONObject;

/**
 * 文字写入图层背景工具类
 * 
 * 内容过多自动分页,生成的图片名 为源文件名加上序号
 * 
 * 落款自动写入格式
 * 
 * 过滤连续出现的换行符
 * 
 * 设置基本属性,调用compound方法即可
 * 
 * @author fule
 */
public class ImageWUtil {

	// 常量字体大小
	public final static int LARGESIZE = 100; // 大字体
	public final static int NORMALSIZE = 50; // 普通字体
	public final static int SMALLSIZE = 30; // 小字体
	// 段间距
	public final static int SECTSIZE = 80;
	// 文字区边距
	public final static int PADDING = 100;
	public final static Color DEAUFT_COLOR = Color.WHITE;

	// 连续书写时的记录位
	int pointIndex;

	// title书写之后的记录位
	int pointOnTitle;

	// 当前第几页
	int indexPage = 1;

	Map<Integer, String> map;

	/**
	 * 设置当前书写的像素位子
	 * 
	 * @return
	 */
	private int setPointIndex(int increment) {
		pointIndex += increment;
		return pointIndex;
	}

	/**
	 * 内容区字体大小
	 */
	private int contentFontSize = NORMALSIZE;

	/**
	 * 标题字体大小
	 */
	private int titleFontSize = LARGESIZE;

	/**
	 * 段间距
	 */
	private int secttSize = SECTSIZE;

	/**
	 * 文本域边距大小
	 */
	private int contentPadding = PADDING;

	/**
	 * 标题字体
	 */
	private String titleFontStyle;

	/**
	 * 设置字体类型
	 * @param titleFontStyle
	 */
	public void setTitleFontStyle(String titleFontStyle) {
		this.titleFontStyle = titleFontStyle;
	}

	public String getTitleFontStyle() {
		return titleFontStyle;
	}

	/**
	 * 标题字体粗细斜体设置
	 * 
	 */
	private int titleFontBlod;
	
	
	/**
	 * 标题字体粗细斜体设置
	 * 
	 */
	public void setTitleFontBlod(int titleFontBlod) {
		this.titleFontBlod = titleFontBlod;
	}
	
	public int getTitleFontBlod() {
		return titleFontBlod;
	}
	
	/**
	 * 内容字体粗细斜体设置
	 */
	private int contentFontBlod;
	
	/**
	 * 内容字体粗细斜体设置
	 * 将同时设置正文与尾款
	 */
	public void setContentFontBlod(int contentFontBlod) {
		this.contentFontBlod = contentFontBlod;
	}
	
	public int getContentFontBlod() {
		return contentFontBlod;
	}
	

	
	/**
	 * 内容字体
	 */
	private String contentFontStyle;

	public void setContentFontStyle(String contentFontStyle) {
		this.contentFontStyle = contentFontStyle;
	}

	public String getContentFontStyle() {
		return contentFontStyle;
	}

	/**
	 * 画笔颜色
	 */

	private Color color;

	/**
	 * 背景图片
	 */
	private File bgFile;

	/**
	 * 设置背景图
	 * 
	 * @param bgFile
	 */
	public void setBgFile(File bgFile) {
		this.bgFile = bgFile;
	}

	/**
	 * 设置画笔颜色 默认白色
	 * 
	 * @param color
	 */
	public void setColor(Color color) {
		this.color = color;
	}

	/**
	 * 设置内容区字体大小 默认NORMALSIZE = 50
	 */
	public void setContentFontSize(int contentFontSize) {
		this.contentFontSize = contentFontSize;
	}

	/**
	 * 设置标题字体大小 默认LARGESIZE = 100
	 */
	public void setTitleFontSize(int titleFontSize) {
		this.titleFontSize = titleFontSize;
	}

	/**
	 * 设置段间距 默认SECTSIZE = 70
	 * 
	 * @param secttSize
	 */
	public void setSecttSize(int secttSize) {
		this.secttSize = secttSize;
	}

	/**
	 * 设置文本边距 默认PADDING70
	 * 
	 * @param contentPadding
	 */
	public void setContentPadding(int contentPadding) {
		this.contentPadding = contentPadding;
	}

	/**
	 * 合成图片
	 * <p>
	 * strTitleString 标题
	 * </p>
	 * <p>
	 * context 正文
	 * </p>
	 * <p>
	 * luokuan 落款
	 * </p>
	 * 分页产生的图片名 递增1
	 * 
	 * @return
	 * @throws Exception
	 */

	public int compound(String strTitleString, String context, String[] luokuan)
			throws Exception {
		int resultCount = 0;// 生成的图片张数
		BufferedImage bi = null;
		try {
			bi = ImageIO.read(bgFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
		int imgWidth = bi.getWidth();
		int ImgHeight = bi.getHeight();
		Graphics2D g = getGraphics(bi);
		Font titleFont = new Font(titleFontStyle, titleFontBlod, titleFontSize);// 标题
		Font contentFont = new Font(contentFontStyle, contentFontBlod,
				contentFontSize);// 内容
		Font luoKuanFont = new Font(contentFontStyle, contentFontBlod,
				contentFontSize);// 落款
		if (strTitleString == null && context == null && luokuan == null) {
			throw new Exception("没有数据,没有写入任何数据");
		} else {
			g.setFont(contentFont);
			Map<Integer, String> pagemap = getPageStrings(imgWidth, ImgHeight,
					strTitleString, context);
			resultCount = pagemap.size();
			for (int i = 1; i <= resultCount; i++) {
				pointIndex = 0;// 初始化
				String pageContent = pagemap.get(i);
				if (strTitleString != null) {
					drawTitle(titleFont, imgWidth, strTitleString, g);
				}
				String[] testContext = getContents(pageContent);// 每一页段数据
				if (testContext != null) {
					for (int j = 0; j < testContext.length; j++) {
						drawContent(imgWidth, testContext[j], g);
					}
					if (pagemap.size() == 1 || i == pagemap.size()) {
						setPointIndex(2 * secttSize);// 设置落款 开始位置
						if (luokuan != null) {
							drawLuoKuan(imgWidth, luokuan, luoKuanFont, g);
						}
					}
				}
				try {
					String fatherPath = bgFile.getParent();
					String fileAbName = bgFile.getName();
					String fn = fileAbName.substring(0,
							fileAbName.lastIndexOf("."));// 文件名前缀
					String filenameString = fatherPath + "/" + fn + i + ".jpg";
					File f = new File(filenameString);
					ImageIO.write(bi, "jpg", f);
					bi = ImageIO.read(bgFile);
					g = getGraphics(bi);
					g.setFont(contentFont);
				} catch (IOException e) {
					e.printStackTrace();
					return 0;
				}
			}
			g.dispose();
			bgFile.delete();// 删除背景
			System.out.println("合成完毕");
			return resultCount;
		}

	}// end

	private Graphics2D getGraphics(BufferedImage bi) {
		Graphics2D g = bi.createGraphics();
		// 字体平滑
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(color);
		return g;
	}

	/**
	 * 写入标题 居中 字数过多换行
	 * 
	 * @param width
	 * @param title
	 * @param g
	 */
	public void drawTitle(Font font, int width, String title, Graphics2D g) {
		AttributedString as = null;
		// title = ToSBC(title);

		int fullLen = (width - contentPadding * 2) / titleFontSize;// 一行的最多容量
		int titleLen = title.length();
		if (titleLen > fullLen) {
			String s = title;
			int writeLen = (s.length() + fullLen - 1) / fullLen;// 可写入行数
			String string;
			int sum = 0;
			for (int i = 0; i < writeLen - 1; i++) {
				int begin = i * fullLen;
				int end = begin + fullLen;
				string = s.substring(begin, end);
				int sl = string.length();// 实际每行写入字数
				as = new AttributedString(string);
				as.addAttribute(TextAttribute.FONT, font);
				g.drawString(as.getIterator(), width / 2 - sl / 2
						* titleFontSize, pointIndex
						+ (titleFontSize + secttSize / 2) * (i + 1));// i+1
																		// 去除二段重行
			}
			string = s.substring((writeLen - 1) * fullLen);
			as = new AttributedString(string);
			as.addAttribute(TextAttribute.FONT, font);
			g.drawString(as.getIterator(), width / 2 - string.length() / 2
					* titleFontSize, pointIndex
					+ (titleFontSize + secttSize / 2) * writeLen);// 最后一行
			sum += (titleFontSize + secttSize) * writeLen;
			setPointIndex(sum);
		} else {
			as = new AttributedString(title);
			as.addAttribute(TextAttribute.FONT, font);
			g.drawString(as.getIterator(), width / 2 - titleLen / 2
					* titleFontSize, setPointIndex(titleFontSize + secttSize));
			pointIndex=pointIndex+(int)Math.ceil(1.5*secttSize);

		}
		pointOnTitle = pointIndex;
	}
		
	/*
	 * 备用方法,形式如段落
	 * public void drawTitle(Font font, int width, String title, Graphics2D g) {
		AttributedString as = null;
		// title = ToSBC(title);
		// TODO
		int fullLen = (width - contentPadding * 2) / titleFontSize;// 一行的最多容量
		Map<Integer, String> map = rowAttr(title, fullLen);
		Object[] keys = map.keySet().toArray();
		String tempStr = "";
		if (keys.length == 1) {// 只有一行
			tempStr = map.get(0);
			as = new AttributedString(title);
			as.addAttribute(TextAttribute.FONT, font);
			g.drawString(as.getIterator(), width / 2 - tempStr.length() / 2
					* titleFontSize, setPointIndex(titleFontSize + secttSize));
		} else {
			int sum = 0;
			int writeLen = keys.length;
			for (int i = 0; i < writeLen - 1; i++) {
				tempStr = map.get(keys[i]);
				as = new AttributedString(tempStr);
				as.addAttribute(TextAttribute.FONT, font);
				int sl = tempStr.length();
				g.drawString(as.getIterator(), width / 2 - sl / 2
						* titleFontSize, pointIndex
						+ (titleFontSize + secttSize / 2) * (i + 1));// i+1
			}
			tempStr = map.get(keys.length - 1);
			as = new AttributedString(tempStr);
			as.addAttribute(TextAttribute.FONT, font);
			g.drawString(as.getIterator(), width / 2 - writeLen / 2
					* titleFontSize, pointIndex
					+ (titleFontSize + secttSize / 2) * writeLen);// 最后一行
			sum += (titleFontSize + secttSize) * writeLen;
			setPointIndex(sum);
		}
		pointOnTitle = pointIndex;
	}
*/
	/**
	 * 写入落款
	 * 
	 * 从后面往前写
	 * 
	 * @param width
	 * @param wsString
	 *            内容
	 * @param g
	 * @throws Exception
	 */
	public void drawLuoKuan(int width, String[] wsString, Font font,
			Graphics2D g) throws Exception {
		AttributedString as = null;
		int padding = 2;
		int fontsize = font.getSize();
		int fullLen = (width - contentPadding * 2) / fontsize;// 一行的最多容量
		for (int i = 0; i < wsString.length; i++) {
			// wsString[i] = ToSBC(wsString[i]);
			if (wsString[i].length() > fullLen) {
				throw new Exception("落款长度过长");
			}
			as = new AttributedString(wsString[i]);
			as.addAttribute(TextAttribute.FONT, font);
			if (wsString[0].length() > wsString[1].length()) {
				if (i == 0) {
					g.drawString(as.getIterator(),
							(fullLen - wsString[0].length() + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
					setPointIndex(-(secttSize / 2));
				} else {
					g.drawString(
							as.getIterator(),
							(fullLen
									- wsString[1].length()
									+ ((wsString[1].length() - wsString[0]
											.length()) / 2) + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
				}
			} else if (wsString[0].length() < wsString[1].length()) {
				if (i == 0) {
					g.drawString(
							as.getIterator(),
							(fullLen
									- wsString[0].length()
									+ ((wsString[0].length() - wsString[1]
											.length()) / 2) + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
					setPointIndex(-(secttSize / 2));
				} else {
					g.drawString(as.getIterator(),
							(fullLen - wsString[1].length() + padding)
									* fontsize, setPointIndex(fontsize
									+ secttSize));
				}
			} else {
				g.drawString(as.getIterator(),
						(fullLen - wsString[0].length() + padding) * fontsize,
						setPointIndex(fontsize + secttSize));
				setPointIndex(-(secttSize / 2));
			}
		}

	}

	/**
	 * 书写段落
	 * 
	 * 文本边距为1个字符
	 * 
	 * 写入段落 内容区 一个字的像素为SMALLSIZE
	 * 
	 * @param width
	 *            图片宽度
	 * @param height
	 *            图片高度
	 * @param content
	 *            段落文本
	 * @param g
	 */
	public void drawContent(int width, String content, Graphics2D g) {
		// content = ToSBC(content);
		// TODO
		int fullFontLen = (width - contentPadding * 2) / contentFontSize;// 满行写入
																			// 可写长度(字数)
		String duanshou;
		int writeLen;
		int sum = 0;
		if (content.length() < fullFontLen) {
			duanshou = content;
			writeLen = 1;
			g.drawString(duanshou, contentPadding, pointIndex+(2 *secttSize));
			setPointIndex(2 * (int)Math.ceil(1.5*secttSize));
		} else {
			Map<Integer, String> map = rowAttr(content, fullFontLen);
			Object[] keys = map.keySet().toArray();
			duanshou =map.get(keys[0]) ;//段首行
			g.drawString(duanshou, contentPadding + 2 * contentFontSize,pointIndex +(int)Math.ceil(1.5*secttSize));//写入段首行  缩进两个字符
			
			for (int i = 1; i < keys.length; i++) {
				String tempStr = map.get(keys[i]);
				g.drawString(tempStr, contentPadding, pointIndex +(int)Math.ceil(1.5*secttSize)
						+ (int)Math.ceil(1.5*secttSize) * i);
			}
			writeLen = keys.length;
			sum += (((int)Math.ceil(1.5*secttSize)) * (writeLen));// 段落之间的间隙
			setPointIndex(sum + secttSize);
		}

	}

	/**
	 * 内容得知行属性
	 * 
	 * @param str
	 *            段落文本
	 * @return map key:句编号 values:内容 //TODO 内容得知行属性
	 */
	public Map<Integer, String> rowAttr(String str, int fullFontLen) {
		Map<Integer, String> map = new HashMap<Integer, String>();
		int fullNum = 2 * fullFontLen;// 满行可写入数字字母的 个数 汉字为双倍
		int i = 0;
		char[] strArr = str.toCharArray();
		int count = 0;// 控制句容量 计数子
		int index = 0;// 句号
		while (true) {
			if (strArr[i] == 32 || strArr[i] < 127) {
				count++;
			} else {
				count += 2;// 汉字两个字符像素位子
			}
			if (fullNum <= count) {
				String s = str.substring(0, i);
				if (index==0) {//段首行 满容量缩进两个字符
					s=str.substring(0,i-getSuojinNum(s));
				}
				map.put(index, s);
				str = str.substring(s.length());// 取后面新的一句
				strArr = str.toCharArray();
				index++;
				count = 0;
				i = 0;
				continue;
			}
			i++;
			if (getOccupyNum(str) <= fullNum) {// 最后一句容量小于临界
				map.put(index, str);
				break;
			}

		}
		return map;

	}
	
	/**
	 * 缩进需要挤出的字符数
	 * 缩进两个汉字字符
	 * @param str
	 * @return
	 */
	private int getSuojinNum(String str){
		char[] strArr = str.toCharArray();
		int count = 0;//统计像素
		int sum = 0;//统计字数
		int i = strArr.length-1;
		while(true){
			if (strArr[i] == 32 || strArr[i] < 127) {
				count++;
			} else {
				count += 2;// 汉字两个字符像素位子
			}
			sum++;
			if(count>=4){
				break;
			}
		}
		return sum;
	}

	/**
	 * 得到一句容量
	 */
	private int getOccupyNum(String str) {
		int count = 0;
		char[] ch = str.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			if (ch[i] == 32 || ch[i] < 127) {
				count++;
			} else {
				count += 2;
			}
		}

		return count;
	}

	/**
	 * 是否存在下一页
	 * 
	 * @param point
	 * @param height
	 * @return
	 */
	public boolean hasNextPage(int height) {
		if (pointIndex > (height - 2 * secttSize)) {
			// 存在下一页新页开始
			pointIndex = 0;
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 写入内容时是否产生分页 TODO 第一段就超出页 除第一段之后的超页
	 * 
	 * @param height
	 *            高度
	 * @param width
	 *            宽度
	 * @param testContext
	 * @return map<页码,内容>
	 */
	private Map<Integer, String> getPageStrings(int width, int height,
			String title, String testContext) {
		// title = ToSBC(title);
		int titleFullLen = (width - contentPadding * 2) / titleFontSize;// 一行标题的最多容量
		int titleWriteLen = (title.length() + titleFullLen - 1) / titleFullLen;// 标题占有行
		int titleHeight = titleWriteLen * (titleFontSize + secttSize);// 标题高度

		int fullFontLen = (width - contentPadding * 2) / contentFontSize;// 满行写入可写长度(字数)

		int contentHeight = getDuanLuoHeight(fullFontLen, titleHeight, height,
				testContext);

		// int contentHeight = getContents(testContext).length * 2 *
		// secttSize;// 满区内容段落间距总高度

		int bgTotalRows = (height - titleHeight - contentHeight) / secttSize
				- 3;// 除去落款,背景可书写总行数

		int vTotalRows = (testContext.length() + fullFontLen - 1) / fullFontLen;// 实际内容所需行数

		int fullWord = bgTotalRows * fullFontLen;// 满屏写入内容字数
		if (map == null) {
			map = new HashMap<Integer, String>();
		}
		if (vTotalRows < bgTotalRows) {
			map.put(indexPage, testContext);
		} else {
			int count = 0;

			int pageCount = (vTotalRows + bgTotalRows - 1) / bgTotalRows;// 需要总页数
			String string;
			for (int i = count; i < pageCount; i++) {
				if (i == pageCount - 1) {
					string = testContext.substring(i * fullWord);// 最后一页
				} else {
					string = testContext.substring(i * fullWord, (i + 1)
							* fullWord);
				}
				// System.out.println("当页内容:\n"+string);
				map.put(indexPage, string);
				indexPage++;

			}
		}
		System.out.println("总页数" + map.size());
		return map;
	}

	// 每页段落总间隙
	// 如果是第一页 写入 如果是其他的 算满屏额
	private int getDuanLuoHeight(int fullFontLen, int titleHeight, int height,
			String testContext) {
		int bgTotalRows = (height - titleHeight) / secttSize - 4;// 满页可写入行数
		int fullWord = bgTotalRows * fullFontLen;// 满屏写入内容字数
		int wlen = testContext.length();
		if (wlen < fullWord) {
			return getContents(testContext).length * 2 * secttSize;
		} else {
			return getContents(testContext.substring(0, fullWord)).length * 2
					* secttSize;
		}
	}

	/**
	 * 字符串处理 解析出段落
	 */
	private String[] getContents(String str) {
		while (str.startsWith("\r\n")) {
			str = str.substring(2);
		}
		str = str.replaceAll("(\r?\n(\\s*\r?\n)+)", "\r\n");// 处理多个连续的\r\n
															// 置换成一个/r/n
		String[] a = str.split("\r\n");
		return a.length == 0 ? null : a;
	}

	/**
	 * 字符串处理
	 * 
	 * @param str
	 * @return
	 * @deprecated
	 */
	private String[] getContent(String str) {

		String string = str.replace("\r\n", "");
		string = string.replace("<p>", "{");
		string = string.replace("</p>", "}");
		List<String> list = new ArrayList<String>();
		while (string.indexOf("{") > -1) {
			int start = string.indexOf("{") + 1;
			int end = string.indexOf("}");
			String st = string.substring(start, end);
			list.add(st);
			string = string.substring(end + 1);
		}
		for (int i = 0; i < list.size(); i++) {
			if ("".equals(list.get(i)) || list.get(i) == null) {
				list.remove(i);
			}
		}
		String[] a = list.toArray(new String[0]);
		return a.length == 0 ? null : a;
	}

	/**
	 * 置换日期格式
	 * 
	 * @param c
	 * @return
	 */
	public static char conversionNum(int c) {
		char rc = 0;
		switch (c) {
		case 1:
			rc = '一';
			break;
		case 2:
			rc = '二';
			break;
		case 3:
			rc = '三';
			break;
		case 4:
			rc = '四';
			break;
		case 5:
			rc = '五';
			break;
		case 6:
			rc = '六';
			break;
		case 7:
			rc = '七';
			break;
		case 8:
			rc = '八';
			break;
		case 9:
			rc = '九';
			break;
		case 10:
			rc = '十';
			break;
		case 0:
			rc = '〇';
		}
		return rc;
	}

	/**
	 * 解析月/日
	 * 
	 * @param a
	 * @return
	 */
	public static String conversionMouth(int a) {
		if (a <= 10) {
			return String.valueOf(conversionNum(a));
		} else {
			int gw = a % 10;
			int sw = a / 10;
			String swString = String.valueOf(conversionNum(sw));
			String gwString = String.valueOf(conversionNum(gw));
			if (a < 20) {
				return "十" + gwString;
			} else {
				return swString + "十" + gwString;
			}
		}
	}

	// 首零的处理
	public String removeBeginZ(String str) {
		if (str.startsWith("0")) {
			int index = str.indexOf("0");
			return str.substring(index);
		} else {
			return str;
		}

	}

	/**
	 * 转化为中文日期格式 形式如:二〇一〇年十月二十一
	 * 
	 * 传入格式:yyyy-MM-dd
	 * 
	 * @param str
	 * @return 中文日期格式
	 * @throws Exception
	 */
	public static String toCN_Date(String str) throws Exception {
		String eL = "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}";// 匹配正则
		Pattern p = Pattern.compile(eL);
		Matcher m = p.matcher(str);
		boolean dateFlag = m.matches();
		if (dateFlag) {
			String[] strings = str.split("-");
			char[] y = strings[0].toCharArray();// 年
			StringBuffer cndate = new StringBuffer();
			for (int i = 0; i < y.length; i++) {
				char cy = conversionNum((int) y[i] - 48);
				cndate.append(cy);
			}
			String mounth = conversionMouth(Integer.parseInt(String
					.valueOf(strings[1])));
			String daString = conversionMouth(Integer.parseInt(String
					.valueOf(strings[2])));
			cndate.append("年" + mounth + "月");
			cndate.append(daString + "日");
			return cndate.toString();
		} else {
			throw new Exception("请使用正确格式的日期字符串,格式为yyyy-MM-dd");
		}
	}
/**
*//获得当前字体列表
*/
public List<String> getSysFontList(){
List<String> fl = new ArrayList<String>();
		String[]   fontlist   = 
			    GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); 
		String except = "^[a-zA-Z0-9_ -.]+$";  //过滤英文字体
		Pattern pattern = Pattern.compile(except);
		for (String string : fontlist) {
			if (!pattern.matcher(string).matches()) {
				System.out.println(string);
				fl.add(string);
			}	
		}
		
return fl;
}
	/**
	 * Test
	 * 
	 * @param args
	 * @throws Exception
	 * 
	 */

	public static void main(String[] args) throws Exception {

		File bgFile = new File("D:/bgb.jpg");

		ImageWUtil iUtil = new ImageWUtil();
		iUtil.setBgFile(bgFile);// 设置背景图片
		iUtil.setColor(Color.BLACK);// 设置画笔颜色
		iUtil.setTitleFontSize(42);// 设置标题字体大小 一号    42二号
		iUtil.setContentFontSize(30);// 设置正文字体    小四号
		iUtil.setContentPadding(42);// 设置边距 距背景边界
		iUtil.setSecttSize(30);// 设置行高 段间距默认两倍行高
		
		iUtil.setTitleFontBlod(Font.BOLD); //设置字体的样式
		iUtil.setContentFontBlod(Font.PLAIN);
		
		iUtil.setTitleFontStyle("黑体");//设置字体的类型
		iUtil.setContentFontStyle("宋体");
		
		
		String strTitleString = "关于积极参与2012第二届";
		String context = "积极参与积极参与处室、厅直各单位:\r\n\r\n"
				+ "组织开展评选活动组织开展评选活动经启动," + "公众参与网上投票评比时间自2012年9月20日"
				+ "起至10月15日23时止。"
				+ "\r\n\r\n\r\n\r\n本次评选活动为有奖评选," +
				"fdfsffsdfsdfsdfsdfsfs欢组织开展评选活动。各单位要认真"
				+ "组织开展评选活动,组织开展评选活动经启动将评选活动通组织开展评选活动经启动。"
				+ " \r\n网址:http://www.jxsl.gov.cn/sltvote/";
		String[] luokuan = new String[] { "酱油部",
				ImageWUtil.toCN_Date("2012-9-21") };
		System.out.println(ImageWUtil.toCN_Date("2012-9-21"));
		//iUtil.compound(strTitleString, context , luokuan);
		
	}

}

你可能感兴趣的:(Graphics2D)