java中常用的工具类(三)

一、连接数据库的综合类

package com.itjh.javaUtil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDriver;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;

/**
 * 连接数据库的综合类。</br>
 * 依赖jar包:commons.dbcp-1.4,commons.dbutils-1.3,commons.pool-1.5.4包。
 * 
 * @author 宋立君
 * @date 2014年07月03日
 */

public class DBUtil {

	private String dri = null;
	private String url = null;
	private String username = null;
	private String password = null;
	private String poolName = null; // 连接池名称
	private ObjectPool connectionPool = null; // 连接池
	// 对应的定时查询类
	private QueryThread queryThread = null;

	/**
	 * 功能:构造函数
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param dri
	 *            驱动全类名,例如:com.mysql.jdbc.Driver。
	 * @param url
	 *            数据库url连接,例如:
	 *            "jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"
	 * @param userName
	 *            数据库用户名,例如:root
	 * @param password
	 *            数据库密码,例如:abc
	 * @param poolName
	 *            创建的数据库连接池的名称,例如mypool,注意一个web容器此名称不能重复。
	 */
	public DBUtil(String dri, String url, String userName, String password,
			String poolName) {
		this.dri = dri;
		this.url = url;
		this.username = userName;
		this.password = password;
		this.poolName = poolName;
	}

	/**
	 * 执行sql。
	 * 
	 * @param conn
	 *            连接
	 * @param pstm
	 *            PreparedStatement
	 * @return int 执行sql对应的影响行。
	 * @throws SQLException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public int execute(Connection conn, PreparedStatement pstm)
			throws SQLException {
		try {
			return pstm.executeUpdate();
		} finally {
			Close(conn);
		}
	}

	/**
	 * 查询sql。
	 * 
	 * @param conn
	 *            连接
	 * @param pstm
	 *            PreparedStatement
	 * @return List<Map<String,Object>> 查询的结果集
	 * @throws SQLException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public List<Map<String, Object>> query(Connection conn,
			PreparedStatement pstm) throws SQLException {
		try {
			return resultSetToList(pstm.executeQuery());
		} finally {
			Close(conn);
		}
	}

	/**
	 * 功能:ResultSet 转为List<Map<String,Object>>
	 * 
	 * 
	 * @param rs
	 *            ResultSet 原始数据集
	 * @return List<Map<String,Object>>
	 * @throws java.sql.SQLException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	private List<Map<String, Object>> resultSetToList(ResultSet rs)
			throws java.sql.SQLException {
		if (rs == null)
			return Collections.EMPTY_LIST;

		ResultSetMetaData md = rs.getMetaData(); // 得到结果集(rs)的结构信息,比如字段数、字段名等
		int columnCount = md.getColumnCount(); // 返回此 ResultSet 对象中的列数
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		Map<String, Object> rowData = new HashMap<String, Object>();
		while (rs.next()) {
			rowData = new HashMap<String, Object>(columnCount);
			for (int i = 1; i <= columnCount; i++) {
				rowData.put(md.getColumnName(i), rs.getObject(i));
			}
			list.add(rowData);
		}
		return list;
	}

	/**
	 * 查询sql语句。
	 * 
	 * @param sql
	 *            被执行的sql语句
	 * @return List<Map<String,Object>>
	 * @throws SQLException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public List<Map<String, Object>> query(String sql) throws SQLException {
		List<Map<String, Object>> results = null;
		Connection conn = null;
		try {
			conn = getConnection();
			QueryRunner qr = new QueryRunner();
			results = qr.query(conn, sql, new MapListHandler());
		} finally {
			Close(conn);
		}
		return results;
	}

	/**
	 * 根据参数查询sql语句
	 * 
	 * @param sql
	 *            sql语句
	 * @param param
	 *            参数
	 * @return List<Map<String,Object>>
	 * @throws SQLException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public List<Map<String, Object>> query(String sql, Object param)
			throws SQLException {
		List<Map<String, Object>> results = null;
		Connection conn = null;
		try {
			conn = getConnection();
			QueryRunner qr = new QueryRunner();
			results = (List<Map<String, Object>>) qr.query(conn, sql, param,
					new MapListHandler());
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			Close(conn);
		}
		return results;
	}

	/**
	 * 执行sql语句
	 * 
	 * @param sql
	 *            被执行的sql语句
	 * @return 受影响的行
	 * @throws Exception
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public int execute(String sql) throws Exception {
		Connection conn = getConnection();
		int rows = 0;
		try {
			QueryRunner qr = new QueryRunner();
			rows = qr.update(conn, sql);
		} finally {
			Close(conn);
		}
		return rows;
	}

	/**
	 * 执行含参数的sql语句
	 * 
	 * @param sql
	 *            被执行的sql语句
	 * @param params
	 *            参数
	 * @return 返回受影响的行
	 * @throws Exception
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public int execute(String sql, Object[] params) throws Exception {
		Connection conn = getConnection();
		int rows = 0;
		try {
			QueryRunner qr = new QueryRunner();
			rows = qr.update(conn, sql, params);
		} finally {
			Close(conn);
		}
		return rows;
	}

	/**
	 * 关闭连接
	 * 
	 * @param conn
	 * @throws SQLException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public void Close(Connection conn) throws SQLException {
		if (conn != null) {
			conn.close();
		}
		DbUtils.closeQuietly(conn);
	}

	/**
	 * 启动连接池
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	private void StartPool() {
		try {
			Class.forName(dri);
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		if (connectionPool != null) {
			ShutdownPool();
		}
		try {
			connectionPool = new GenericObjectPool(null);
			ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
					url, username, password);
			PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
					connectionFactory, connectionPool, null, "SELECT 1", false,
					true);
			Class.forName("org.apache.commons.dbcp.PoolingDriver");
			PoolingDriver driver = (PoolingDriver) DriverManager
					.getDriver("jdbc:apache:commons:dbcp:");
			driver.registerPool(poolName, poolableConnectionFactory.getPool());

		} catch (Exception e) {
			e.printStackTrace();
		}
		// 开启查询程序
		queryThread = new QueryThread(this);
		queryThread.start();
	}

	/**
	 * 关闭连接池
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	private void ShutdownPool() {
		try {
			PoolingDriver driver = (PoolingDriver) DriverManager
					.getDriver("jdbc:apache:commons:dbcp:");
			driver.closePool(poolName);
			// 关闭定时查询
			queryThread.setStartQuery(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 得到一个连接
	 * 
	 * @return
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public synchronized Connection getConnection() {
		Connection conn = null;
		try {
			if (connectionPool == null)
				StartPool();
			conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:"
					+ poolName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
}

/**
 * 当连接池启动后会自动定时查询数据库,防止数据库连接超时。
 * 
 * @author 宋立君
 * @date 2014年07月03日
 */
class QueryThread extends Thread {

	private DBUtil dbUtil = null;
	// 是否开启查询
	private boolean startQuery = true;

	/**
	 * 功能:对应的数据库连接。
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param dbUtil
	 *            数据库连接
	 */
	public QueryThread(DBUtil dbUtil) {
		this.dbUtil = dbUtil;
	}

	public void run() {
		while (true) {
			try {
				if (startQuery) {
					this.dbUtil.query("select 1");
				}
				// System.out.println(startQuery+"   123");
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					Thread.sleep(120000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void setStartQuery(boolean startQuery) {
		// System.out.println("startQuery shut:"+startQuery);
		this.startQuery = startQuery;
	}
}

二、DES加密和解密

package com.itjh.javaUtil;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * DES加密和解密。
 * 
 * @author 宋立君
 * @date 2014年07月03日
 */
public class DESUtil {

	/** 安全密钥 */
	private String keyData = "ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstwxyz0123456789-_.";

	/**
	 * 功能:构造
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public DESUtil() {
	}

	/**
	 * 功能:构造
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param keyData
	 *            key
	 */
	public DESUtil(String key) {
		this.keyData = key;
	}

	/**
	 * 功能:加密 (UTF-8)
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param source
	 *            源字符串
	 * @param charSet
	 *            编码
	 * @return String
	 * @throws UnsupportedEncodingException
	 *             编码异常
	 */
	public String encrypt(String source) throws UnsupportedEncodingException {
		return encrypt(source, "UTF-8");
	}

	/**
	 * 
	 * 功能:解密 (UTF-8)
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param encryptedData
	 *            被加密后的字符串
	 * @return String
	 * @throws UnsupportedEncodingException
	 *             编码异常
	 */
	public String decrypt(String encryptedData)
			throws UnsupportedEncodingException {
		return decrypt(encryptedData, "UTF-8");
	}

	/**
	 * 功能:加密
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param source
	 *            源字符串
	 * @param charSet
	 *            编码
	 * @return String
	 * @throws UnsupportedEncodingException
	 *             编码异常
	 */
	public String encrypt(String source, String charSet)
			throws UnsupportedEncodingException {
		String encrypt = null;
		byte[] ret = encrypt(source.getBytes(charSet));
		encrypt = new String(Base64.encode(ret));
		return encrypt;
	}

	/**
	 * 
	 * 功能:解密
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param encryptedData
	 *            被加密后的字符串
	 * @param charSet
	 *            编码
	 * @return String
	 * @throws UnsupportedEncodingException
	 *             编码异常
	 */
	public String decrypt(String encryptedData, String charSet)
			throws UnsupportedEncodingException {
		String descryptedData = null;
		byte[] ret = descrypt(Base64.decode(encryptedData.toCharArray()));
		descryptedData = new String(ret, charSet);
		return descryptedData;
	}

	/**
	 * 加密数据 用生成的密钥加密原始数据
	 * 
	 * @param primaryData
	 *            原始数据
	 * @return byte[]
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	private byte[] encrypt(byte[] primaryData) {

		/** 取得安全密钥 */
		byte rawKeyData[] = getKey();

		/** DES算法要求有一个可信任的随机数源 */
		SecureRandom sr = new SecureRandom();

		/** 使用原始密钥数据创建DESKeySpec对象 */
		DESKeySpec dks = null;
		try {
			dks = new DESKeySpec(keyData.getBytes());
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}

		/** 创建一个密钥工厂 */
		SecretKeyFactory keyFactory = null;
		try {
			keyFactory = SecretKeyFactory.getInstance("DES");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		/** 用密钥工厂把DESKeySpec转换成一个SecretKey对象 */
		SecretKey key = null;
		try {
			key = keyFactory.generateSecret(dks);
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		}

		/** Cipher对象实际完成加密操作 */
		Cipher cipher = null;
		try {
			cipher = Cipher.getInstance("DES");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		}

		/** 用密钥初始化Cipher对象 */
		try {
			cipher.init(Cipher.ENCRYPT_MODE, key, sr);
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}

		/** 正式执行加密操作 */
		byte encryptedData[] = null;
		try {
			encryptedData = cipher.doFinal(primaryData);
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}

		/** 返回加密数据 */
		return encryptedData;
	}

	/**
	 * 用密钥解密数据
	 * 
	 * @param encryptedData
	 *            加密后的数据
	 * @return byte[]
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	private byte[] descrypt(byte[] encryptedData) {

		/** DES算法要求有一个可信任的随机数源 */
		SecureRandom sr = new SecureRandom();

		/** 取得安全密钥 */
		byte rawKeyData[] = getKey();

		/** 使用原始密钥数据创建DESKeySpec对象 */
		DESKeySpec dks = null;
		try {
			dks = new DESKeySpec(keyData.getBytes());
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}

		/** 创建一个密钥工厂 */
		SecretKeyFactory keyFactory = null;
		try {
			keyFactory = SecretKeyFactory.getInstance("DES");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		/** 用密钥工厂把DESKeySpec转换成一个SecretKey对象 */
		SecretKey key = null;
		try {
			key = keyFactory.generateSecret(dks);
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		}

		/** Cipher对象实际完成加密操作 */
		Cipher cipher = null;
		try {
			cipher = Cipher.getInstance("DES");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		}

		/** 用密钥初始化Cipher对象 */
		try {
			cipher.init(Cipher.DECRYPT_MODE, key, sr);
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}

		/** 正式执行解密操作 */
		byte decryptedData[] = null;
		try {
			decryptedData = cipher.doFinal(encryptedData);
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}

		return decryptedData;
	}

	/**
	 * 取得安全密钥 此方法作废,因为每次key生成都不一样导致解密加密用的密钥都不一样, 从而导致Given final block not
	 * properly padded错误.
	 * 
	 * @return byte数组
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	private byte[] getKey() {

		/** DES算法要求有一个可信任的随机数源 */
		SecureRandom sr = new SecureRandom();

		/** 为我们选择的DES算法生成一个密钥生成器对象 */
		KeyGenerator kg = null;
		try {
			kg = KeyGenerator.getInstance("DES");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		kg.init(sr);

		/** 生成密钥工具类 */
		SecretKey key = kg.generateKey();

		/** 生成密钥byte数组 */
		byte rawKeyData[] = key.getEncoded();

		return rawKeyData;
	}

}

Base64.java

package com.itjh.javaUtil;

import java.io.*;

/**
 * Base64 编码和解码。
 * 
 * @author 宋立君
 * @date 2014年07月03日
 */
public class Base64 {

	public Base64() {
	}

	/**
	 * 功能:编码字符串
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param data
	 *            源字符串
	 * @return String
	 */
	public static String encode(String data) {
		return new String(encode(data.getBytes()));
	}

	/**
	 * 功能:解码字符串
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param data
	 *            源字符串
	 * @return String
	 */
	public static String decode(String data) {
		return new String(decode(data.toCharArray()));
	}

	/**
	 * 功能:编码byte[]
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param data
	 *            源
	 * @return char[]
	 */
	public static char[] encode(byte[] data) {
		char[] out = new char[((data.length + 2) / 3) * 4];
		for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
			boolean quad = false;
			boolean trip = false;

			int val = (0xFF & (int) data[i]);
			val <<= 8;
			if ((i + 1) < data.length) {
				val |= (0xFF & (int) data[i + 1]);
				trip = true;
			}
			val <<= 8;
			if ((i + 2) < data.length) {
				val |= (0xFF & (int) data[i + 2]);
				quad = true;
			}
			out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
			val >>= 6;
			out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
			val >>= 6;
			out[index + 1] = alphabet[val & 0x3F];
			val >>= 6;
			out[index + 0] = alphabet[val & 0x3F];
		}
		return out;
	}

	/**
	 * 功能:解码
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param data
	 *            编码后的字符数组
	 * @return byte[]
	 */
	public static byte[] decode(char[] data) {

		int tempLen = data.length;
		for (int ix = 0; ix < data.length; ix++) {
			if ((data[ix] > 255) || codes[data[ix]] < 0) {
				--tempLen; // ignore non-valid chars and padding
			}
		}
		// calculate required length:
		// -- 3 bytes for every 4 valid base64 chars
		// -- plus 2 bytes if there are 3 extra base64 chars,
		// or plus 1 byte if there are 2 extra.

		int len = (tempLen / 4) * 3;
		if ((tempLen % 4) == 3) {
			len += 2;
		}
		if ((tempLen % 4) == 2) {
			len += 1;

		}
		byte[] out = new byte[len];

		int shift = 0; // # of excess bits stored in accum
		int accum = 0; // excess bits
		int index = 0;

		// we now go through the entire array (NOT using the 'tempLen' value)
		for (int ix = 0; ix < data.length; ix++) {
			int value = (data[ix] > 255) ? -1 : codes[data[ix]];

			if (value >= 0) { // skip over non-code
				accum <<= 6; // bits shift up by 6 each time thru
				shift += 6; // loop, with new bits being put in
				accum |= value; // at the bottom.
				if (shift >= 8) { // whenever there are 8 or more shifted in,
					shift -= 8; // write them out (from the top, leaving any
					out[index++] = // excess at the bottom for next iteration.
					(byte) ((accum >> shift) & 0xff);
				}
			}
		}

		// if there is STILL something wrong we just have to throw up now!
		if (index != out.length) {
			throw new Error("Miscalculated data length (wrote " + index
					+ " instead of " + out.length + ")");
		}

		return out;
	}

	/**
	 * 功能:编码文件
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param file
	 *            源文件
	 */
	public static void encode(File file) throws IOException {
		if (!file.exists()) {
			System.exit(0);
		}

		else {
			byte[] decoded = readBytes(file);
			char[] encoded = encode(decoded);
			writeChars(file, encoded);
		}
		file = null;
	}

	/**
	 * 功能:解码文件。
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param file
	 *            源文件
	 * @throws IOException
	 */
	public static void decode(File file) throws IOException {
		if (!file.exists()) {
			System.exit(0);
		} else {
			char[] encoded = readChars(file);
			byte[] decoded = decode(encoded);
			writeBytes(file, decoded);
		}
		file = null;
	}

	//
	// code characters for values 0..63
	//
	private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
			.toCharArray();

	//
	// lookup table for converting base64 characters to value in range 0..63
	//
	private static byte[] codes = new byte[256];
	static {
		for (int i = 0; i < 256; i++) {
			codes[i] = -1;
			// LoggerUtil.debug(i + "&" + codes[i] + " ");
		}
		for (int i = 'A'; i <= 'Z'; i++) {
			codes[i] = (byte) (i - 'A');
			// LoggerUtil.debug(i + "&" + codes[i] + " ");
		}

		for (int i = 'a'; i <= 'z'; i++) {
			codes[i] = (byte) (26 + i - 'a');
			// LoggerUtil.debug(i + "&" + codes[i] + " ");
		}
		for (int i = '0'; i <= '9'; i++) {
			codes[i] = (byte) (52 + i - '0');
			// LoggerUtil.debug(i + "&" + codes[i] + " ");
		}
		codes['+'] = 62;
		codes['/'] = 63;
	}

	private static byte[] readBytes(File file) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] b = null;
		InputStream fis = null;
		InputStream is = null;
		try {
			fis = new FileInputStream(file);
			is = new BufferedInputStream(fis);
			int count = 0;
			byte[] buf = new byte[16384];
			while ((count = is.read(buf)) != -1) {
				if (count > 0) {
					baos.write(buf, 0, count);
				}
			}
			b = baos.toByteArray();

		} finally {
			try {
				if (fis != null)
					fis.close();
				if (is != null)
					is.close();
				if (baos != null)
					baos.close();
			} catch (Exception e) {
				System.out.println(e);
			}
		}

		return b;
	}

	private static char[] readChars(File file) throws IOException {
		CharArrayWriter caw = new CharArrayWriter();
		Reader fr = null;
		Reader in = null;
		try {
			fr = new FileReader(file);
			in = new BufferedReader(fr);
			int count = 0;
			char[] buf = new char[16384];
			while ((count = in.read(buf)) != -1) {
				if (count > 0) {
					caw.write(buf, 0, count);
				}
			}

		} finally {
			try {
				if (caw != null)
					caw.close();
				if (in != null)
					in.close();
				if (fr != null)
					fr.close();
			} catch (Exception e) {
				System.out.println(e);
			}
		}

		return caw.toCharArray();
	}

	private static void writeBytes(File file, byte[] data) throws IOException {
		OutputStream fos = null;
		OutputStream os = null;
		try {
			fos = new FileOutputStream(file);
			os = new BufferedOutputStream(fos);
			os.write(data);

		} finally {
			try {
				if (os != null)
					os.close();
				if (fos != null)
					fos.close();
			} catch (Exception e) {
				System.out.println(e);
			}
		}
	}

	private static void writeChars(File file, char[] data) throws IOException {
		Writer fos = null;
		Writer os = null;
		try {
			fos = new FileWriter(file);
			os = new BufferedWriter(fos);
			os.write(data);

		} finally {
			try {
				if (os != null)
					os.close();
				if (fos != null)
					fos.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// /
	// end of test code.
	// /

}

三、ExcelUtil工具类

package com.itjh.javaUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

/**
 * 封装对excel的操作,包括本地读写excel和流中输出excel,支持office 2007。<br/>
 * 依赖于poi-3.9-20121203.jar,poi-ooxml-3.9-20121203.jar,poi-ooxml-schemas-3.9-
 * 20121203.jar,dom4j-1.6.1.jar<br/>
 * 有参构造函数参数为excel的全路径<br/>
 * 
 * @author 宋立君
 * @date 2014年07月03日
 */
public class ExcelUtil {

	// excel文件路径
	private String path = "";

	// 写入excel时,是否自动扩展列宽度来符合内容。
	private boolean autoColumnWidth = false;

	/**
	 * 无参构造函数 默认
	 */
	public ExcelUtil() {
	}

	/**
	 * 有参构造函数
	 * 
	 * @param path
	 *            excel路径
	 */
	public ExcelUtil(String path) {
		this.path = path;
	}

	/**
	 * 读取某个工作簿上的所有单元格的值。
	 * 
	 * @param sheetOrder
	 *            工作簿序号,从0开始。
	 * @return List<Object[]> 所有单元格的值。
	 * @throws IOException
	 *             加载excel文件IO异常。
	 * @throws FileNotFoundException
	 *             excel文件没有找到异常。
	 * @throws InvalidFormatException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public List<Object[]> read(int sheetOrder) throws FileNotFoundException,
			IOException, InvalidFormatException {
		FileInputStream fis = new FileInputStream(path);
		Workbook workbook = WorkbookFactory.create(fis);
		if (fis != null) {
			fis.close();
		}
		Sheet sheet = workbook.getSheetAt(sheetOrder);
		// 用来记录excel值
		List<Object[]> valueList = new LinkedList<Object[]>();
		// 循环遍历每一行、每一列。
		for (Row row : sheet) {
			// 每一行
			Object[] rowObject = null;
			for (Cell cell : row) {
				// cell.getCellType是获得cell里面保存的值的type
				switch (cell.getCellType()) {
				case Cell.CELL_TYPE_BOOLEAN:
					// 得到Boolean对象的方法
					rowObject = CollectionUtil.addObjectToArray(rowObject,
							cell.getBooleanCellValue());
					break;
				case Cell.CELL_TYPE_NUMERIC:
					// 先看是否是日期格式
					if (DateUtil.isCellDateFormatted(cell)) {
						// 读取日期格式
						rowObject = CollectionUtil.addObjectToArray(rowObject,
								cell.getDateCellValue());
					} else {
						DecimalFormat df = new DecimalFormat();
						// 单元格的值,替换掉,
						String value = df.format(cell.getNumericCellValue())
								.replace(",", "");
						// 读取数字
						rowObject = CollectionUtil.addObjectToArray(rowObject,
								value);
					}
					break;
				case Cell.CELL_TYPE_FORMULA:
					// 读取公式
					rowObject = CollectionUtil.addObjectToArray(rowObject,
							cell.getCellFormula());
					break;
				case Cell.CELL_TYPE_STRING:
					// 读取String
					rowObject = CollectionUtil.addObjectToArray(rowObject, cell
							.getRichStringCellValue().toString());
					break;
				}
			}
			// 将这行添加到list。
			valueList.add(rowObject);
		}
		return valueList;
	}

	/**
	 * 读取某个工作簿上的某个单元格的值。
	 * 
	 * @param sheetOrder
	 *            工作簿序号,从0开始。
	 * @param colum
	 *            列数 从1开始
	 * @param row
	 *            行数 从1开始
	 * @return 单元格的值。
	 * @throws Exception
	 *             加载excel异常。
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public String read(int sheetOrder, int colum, int row) throws Exception {
		FileInputStream fis = new FileInputStream(path);
		Workbook workbook = WorkbookFactory.create(fis);
		if (fis != null) {
			fis.close();
		}
		Sheet sheet = workbook.getSheetAt(sheetOrder);
		Row rows = sheet.getRow(row - 1);
		Cell cell = rows.getCell(colum - 1);
		String content = cell.getStringCellValue();
		return content;
	}

	/**
	 * 在指定的工作簿、行、列书写值。
	 * 
	 * @param sheetOrder
	 *            工作簿序号,基于0.
	 * @param colum
	 *            列 基于1
	 * @param row
	 *            行 基于1
	 * @param content
	 *            将要被书写的内容。
	 * @throws Exception
	 *             书写后保存异常。
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public void write(int sheetOrder, int colum, int row, String content)
			throws Exception {
		FileInputStream fis = new FileInputStream(path);
		Workbook workbook = WorkbookFactory.create(fis);
		if (fis != null) {
			fis.close();
		}
		Sheet sheet = workbook.getSheetAt(sheetOrder);
		Row rows = sheet.createRow(row - 1);
		Cell cell = rows.createCell(colum - 1);
		cell.setCellValue(content);
		FileOutputStream fileOut = new FileOutputStream(path);
		workbook.write(fileOut);
		fileOut.close();

	}

	/**
	 * 得到一个工作区最后一条记录的序号,相当于这个工作簿共多少行数据。
	 * 
	 * @param sheetOrder
	 *            工作区序号
	 * @return int 序号。
	 * @throws IOException
	 *             根据excel路径加载excel异常。
	 * @throws InvalidFormatException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public int getSheetLastRowNum(int sheetOrder) throws IOException,
			InvalidFormatException {
		FileInputStream fis = new FileInputStream(path);
		Workbook workbook = WorkbookFactory.create(fis);
		if (fis != null) {
			fis.close();
		}
		Sheet sheet = workbook.getSheetAt(sheetOrder);
		return sheet.getLastRowNum();
	}

	/**
	 * 在磁盘生成一个含有内容的excel,路径为path属性
	 * 
	 * @param sheetName
	 *            导出的sheet名称
	 * @param fieldName
	 *            列名数组
	 * @param data
	 *            数据组
	 * @throws IOException
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public void makeExcel(String sheetName, String[] fieldName,
			List<Object[]> data) throws IOException {
		// 在内存中生成工作薄
		HSSFWorkbook workbook = makeWorkBook(sheetName, fieldName, data);
		// 截取文件夹路径
		String filePath = path.substring(0, path.lastIndexOf("\\"));
		// 如果路径不存在,创建路径
		File file = new File(filePath);
		// System.out.println(path+"-----------"+file.exists());
		if (!file.exists())
			file.mkdirs();
		FileOutputStream fileOut = new FileOutputStream(path);
		workbook.write(fileOut);
		fileOut.close();
	}

	/**
	 * 在输出流中导出excel。
	 * 
	 * @param excelName
	 *            导出的excel名称 包括扩展名
	 * @param sheetName
	 *            导出的sheet名称
	 * @param fieldName
	 *            列名数组
	 * @param data
	 *            数据组
	 * @param response
	 *            response
	 * @throws IOException
	 *             转换流时IO错误
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	public void makeStreamExcel(String excelName, String sheetName,
			String[] fieldName, List<Object[]> data,
			HttpServletResponse response) throws IOException {
		OutputStream os = null;
		response.reset(); // 清空输出流
		os = response.getOutputStream(); // 取得输出流
		response.setHeader("Content-disposition", "attachment; filename="
				+ new String(excelName.getBytes(), "ISO-8859-1")); // 设定输出文件头
		response.setContentType("application/msexcel"); // 定义输出类型
		// 在内存中生成工作薄
		HSSFWorkbook workbook = makeWorkBook(sheetName, fieldName, data);
		os.flush();
		workbook.write(os);
	}

	/**
	 * 根据条件,生成工作薄对象到内存。
	 * 
	 * @param sheetName
	 *            工作表对象名称
	 * @param fieldName
	 *            首列列名称
	 * @param data
	 *            数据
	 * @return HSSFWorkbook
	 * @author 宋立君
	 * @date 2014年07月03日
	 */
	private HSSFWorkbook makeWorkBook(String sheetName, String[] fieldName,
			List<Object[]> data) {
		// 用来记录最大列宽,自动调整列宽。
		Integer collength[] = new Integer[fieldName.length];

		// 产生工作薄对象
		HSSFWorkbook workbook = new HSSFWorkbook();
		// 产生工作表对象
		HSSFSheet sheet = workbook.createSheet();
		// 为了工作表能支持中文,设置字符集为UTF_16
		workbook.setSheetName(0, sheetName);
		// 产生一行
		HSSFRow row = sheet.createRow(0);
		// 产生单元格
		HSSFCell cell;
		// 写入各个字段的名称
		for (int i = 0; i < fieldName.length; i++) {
			// 创建第一行各个字段名称的单元格
			cell = row.createCell((short) i);
			// 设置单元格内容为字符串型
			cell.setCellType(HSSFCell.CELL_TYPE_STRING);
			// 为了能在单元格中输入中文,设置字符集为UTF_16
			// cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			// 给单元格内容赋值
			cell.setCellValue(new HSSFRichTextString(fieldName[i]));
			// 初始化列宽
			collength[i] = fieldName[i].getBytes().length;
		}
		// 临时单元格内容
		String tempCellContent = "";
		// 写入各条记录,每条记录对应excel表中的一行
		for (int i = 0; i < data.size(); i++) {
			Object[] tmp = data.get(i);
			// 生成一行
			row = sheet.createRow(i + 1);
			for (int j = 0; j < tmp.length; j++) {
				cell = row.createCell((short) j);
				// 设置单元格字符类型为String
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);
				tempCellContent = (tmp[j] == null) ? "" : tmp[j].toString();
				cell.setCellValue(new HSSFRichTextString(tempCellContent));

				// 如果自动调整列宽度。
				if (autoColumnWidth) {
					if (j >= collength.length) { // 标题列数小于数据列数时。
						collength = CollectionUtil.addObjectToArray(collength,
								tempCellContent.getBytes().length);
					} else {
						// 如果这个内容的宽度大于之前最大的,就按照这个设置宽度。
						if (collength[j] < tempCellContent.getBytes().length) {
							collength[j] = tempCellContent.getBytes().length;
						}
					}
				}
			}
		}

		// 自动调整列宽度。
		if (autoColumnWidth) {
			// 调整列为这列文字对应的最大宽度。
			for (int i = 0; i < fieldName.length; i++) {
				sheet.setColumnWidth(i, collength[i] * 2 * 256);
			}
		}
		return workbook;
	}

	/**
	 * 功能:设置写入excel时,是否自动扩展列宽度来符合内容,默认为false。
	 * 
	 * @author 宋立君
	 * @date 2014年07月03日
	 * @param autoColumnWidth
	 *            true或者false
	 */
	public void setAutoColumnWidth(boolean autoColumnWidth) {
		this.autoColumnWidth = autoColumnWidth;
	}
}


  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值