java常用工具类(三)

时间:2023-03-09 02:46:15
java常用工具类(三)

一、连接数据库的综合类

  1. package com.itjh.javaUtil;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.ResultSetMetaData;
  7. import java.sql.SQLException;
  8. import java.util.ArrayList;
  9. import java.util.Collections;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import org.apache.commons.dbcp.ConnectionFactory;
  14. import org.apache.commons.dbcp.DriverManagerConnectionFactory;
  15. import org.apache.commons.dbcp.PoolableConnectionFactory;
  16. import org.apache.commons.dbcp.PoolingDriver;
  17. import org.apache.commons.dbutils.DbUtils;
  18. import org.apache.commons.dbutils.QueryRunner;
  19. import org.apache.commons.dbutils.handlers.MapListHandler;
  20. import org.apache.commons.pool.ObjectPool;
  21. import org.apache.commons.pool.impl.GenericObjectPool;
  22. /**
  23. * 连接数据库的综合类。</br>
  24. * 依赖jar包:commons.dbcp-1.4,commons.dbutils-1.3,commons.pool-1.5.4包。
  25. *
  26. * @author 宋立君
  27. * @date 2014年07月03日
  28. */
  29. public class DBUtil {
  30. private String dri = null;
  31. private String url = null;
  32. private String username = null;
  33. private String password = null;
  34. private String poolName = null; // 连接池名称
  35. private ObjectPool connectionPool = null; // 连接池
  36. // 对应的定时查询类
  37. private QueryThread queryThread = null;
  38. /**
  39. * 功能:构造函数
  40. *
  41. * @author 宋立君
  42. * @date 2014年07月03日
  43. * @param dri
  44. *            驱动全类名,例如:com.mysql.jdbc.Driver。
  45. * @param url
  46. *            数据库url连接,例如:
  47. *            "jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"
  48. * @param userName
  49. *            数据库用户名,例如:root
  50. * @param password
  51. *            数据库密码,例如:abc
  52. * @param poolName
  53. *            创建的数据库连接池的名称,例如mypool,注意一个web容器此名称不能重复。
  54. */
  55. public DBUtil(String dri, String url, String userName, String password,
  56. String poolName) {
  57. this.dri = dri;
  58. this.url = url;
  59. this.username = userName;
  60. this.password = password;
  61. this.poolName = poolName;
  62. }
  63. /**
  64. * 执行sql。
  65. *
  66. * @param conn
  67. *            连接
  68. * @param pstm
  69. *            PreparedStatement
  70. * @return int 执行sql对应的影响行。
  71. * @throws SQLException
  72. * @author 宋立君
  73. * @date 2014年07月03日
  74. */
  75. public int execute(Connection conn, PreparedStatement pstm)
  76. throws SQLException {
  77. try {
  78. return pstm.executeUpdate();
  79. } finally {
  80. Close(conn);
  81. }
  82. }
  83. /**
  84. * 查询sql。
  85. *
  86. * @param conn
  87. *            连接
  88. * @param pstm
  89. *            PreparedStatement
  90. * @return List<Map<String,Object>> 查询的结果集
  91. * @throws SQLException
  92. * @author 宋立君
  93. * @date 2014年07月03日
  94. */
  95. public List<Map<String, Object>> query(Connection conn,
  96. PreparedStatement pstm) throws SQLException {
  97. try {
  98. return resultSetToList(pstm.executeQuery());
  99. } finally {
  100. Close(conn);
  101. }
  102. }
  103. /**
  104. * 功能:ResultSet 转为List<Map<String,Object>>
  105. *
  106. *
  107. * @param rs
  108. *            ResultSet 原始数据集
  109. * @return List<Map<String,Object>>
  110. * @throws java.sql.SQLException
  111. * @author 宋立君
  112. * @date 2014年07月03日
  113. */
  114. private List<Map<String, Object>> resultSetToList(ResultSet rs)
  115. throws java.sql.SQLException {
  116. if (rs == null)
  117. return Collections.EMPTY_LIST;
  118. ResultSetMetaData md = rs.getMetaData(); // 得到结果集(rs)的结构信息,比如字段数、字段名等
  119. int columnCount = md.getColumnCount(); // 返回此 ResultSet 对象中的列数
  120. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  121. Map<String, Object> rowData = new HashMap<String, Object>();
  122. while (rs.next()) {
  123. rowData = new HashMap<String, Object>(columnCount);
  124. for (int i = 1; i <= columnCount; i++) {
  125. rowData.put(md.getColumnName(i), rs.getObject(i));
  126. }
  127. list.add(rowData);
  128. }
  129. return list;
  130. }
  131. /**
  132. * 查询sql语句。
  133. *
  134. * @param sql
  135. *            被执行的sql语句
  136. * @return List<Map<String,Object>>
  137. * @throws SQLException
  138. * @author 宋立君
  139. * @date 2014年07月03日
  140. */
  141. public List<Map<String, Object>> query(String sql) throws SQLException {
  142. List<Map<String, Object>> results = null;
  143. Connection conn = null;
  144. try {
  145. conn = getConnection();
  146. QueryRunner qr = new QueryRunner();
  147. results = qr.query(conn, sql, new MapListHandler());
  148. } finally {
  149. Close(conn);
  150. }
  151. return results;
  152. }
  153. /**
  154. * 根据参数查询sql语句
  155. *
  156. * @param sql
  157. *            sql语句
  158. * @param param
  159. *            参数
  160. * @return List<Map<String,Object>>
  161. * @throws SQLException
  162. * @author 宋立君
  163. * @date 2014年07月03日
  164. */
  165. public List<Map<String, Object>> query(String sql, Object param)
  166. throws SQLException {
  167. List<Map<String, Object>> results = null;
  168. Connection conn = null;
  169. try {
  170. conn = getConnection();
  171. QueryRunner qr = new QueryRunner();
  172. results = (List<Map<String, Object>>) qr.query(conn, sql, param,
  173. new MapListHandler());
  174. } catch (SQLException e) {
  175. e.printStackTrace();
  176. } finally {
  177. Close(conn);
  178. }
  179. return results;
  180. }
  181. /**
  182. * 执行sql语句
  183. *
  184. * @param sql
  185. *            被执行的sql语句
  186. * @return 受影响的行
  187. * @throws Exception
  188. * @author 宋立君
  189. * @date 2014年07月03日
  190. */
  191. public int execute(String sql) throws Exception {
  192. Connection conn = getConnection();
  193. int rows = 0;
  194. try {
  195. QueryRunner qr = new QueryRunner();
  196. rows = qr.update(conn, sql);
  197. } finally {
  198. Close(conn);
  199. }
  200. return rows;
  201. }
  202. /**
  203. * 执行含参数的sql语句
  204. *
  205. * @param sql
  206. *            被执行的sql语句
  207. * @param params
  208. *            参数
  209. * @return 返回受影响的行
  210. * @throws Exception
  211. * @author 宋立君
  212. * @date 2014年07月03日
  213. */
  214. public int execute(String sql, Object[] params) throws Exception {
  215. Connection conn = getConnection();
  216. int rows = 0;
  217. try {
  218. QueryRunner qr = new QueryRunner();
  219. rows = qr.update(conn, sql, params);
  220. } finally {
  221. Close(conn);
  222. }
  223. return rows;
  224. }
  225. /**
  226. * 关闭连接
  227. *
  228. * @param conn
  229. * @throws SQLException
  230. * @author 宋立君
  231. * @date 2014年07月03日
  232. */
  233. public void Close(Connection conn) throws SQLException {
  234. if (conn != null) {
  235. conn.close();
  236. }
  237. DbUtils.closeQuietly(conn);
  238. }
  239. /**
  240. * 启动连接池
  241. *
  242. * @author 宋立君
  243. * @date 2014年07月03日
  244. */
  245. private void StartPool() {
  246. try {
  247. Class.forName(dri);
  248. } catch (ClassNotFoundException e1) {
  249. e1.printStackTrace();
  250. }
  251. if (connectionPool != null) {
  252. ShutdownPool();
  253. }
  254. try {
  255. connectionPool = new GenericObjectPool(null);
  256. ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
  257. url, username, password);
  258. PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
  259. connectionFactory, connectionPool, null, "SELECT 1", false,
  260. true);
  261. Class.forName("org.apache.commons.dbcp.PoolingDriver");
  262. PoolingDriver driver = (PoolingDriver) DriverManager
  263. .getDriver("jdbc:apache:commons:dbcp:");
  264. driver.registerPool(poolName, poolableConnectionFactory.getPool());
  265. } catch (Exception e) {
  266. e.printStackTrace();
  267. }
  268. // 开启查询程序
  269. queryThread = new QueryThread(this);
  270. queryThread.start();
  271. }
  272. /**
  273. * 关闭连接池
  274. *
  275. * @author 宋立君
  276. * @date 2014年07月03日
  277. */
  278. private void ShutdownPool() {
  279. try {
  280. PoolingDriver driver = (PoolingDriver) DriverManager
  281. .getDriver("jdbc:apache:commons:dbcp:");
  282. driver.closePool(poolName);
  283. // 关闭定时查询
  284. queryThread.setStartQuery(false);
  285. } catch (SQLException e) {
  286. e.printStackTrace();
  287. }
  288. }
  289. /**
  290. * 得到一个连接
  291. *
  292. * @return
  293. * @author 宋立君
  294. * @date 2014年07月03日
  295. */
  296. public synchronized Connection getConnection() {
  297. Connection conn = null;
  298. try {
  299. if (connectionPool == null)
  300. StartPool();
  301. conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:"
  302. + poolName);
  303. } catch (Exception e) {
  304. e.printStackTrace();
  305. }
  306. return conn;
  307. }
  308. }
  309. /**
  310. * 当连接池启动后会自动定时查询数据库,防止数据库连接超时。
  311. *
  312. * @author 宋立君
  313. * @date 2014年07月03日
  314. */
  315. class QueryThread extends Thread {
  316. private DBUtil dbUtil = null;
  317. // 是否开启查询
  318. private boolean startQuery = true;
  319. /**
  320. * 功能:对应的数据库连接。
  321. *
  322. * @author 宋立君
  323. * @date 2014年07月03日
  324. * @param dbUtil
  325. *            数据库连接
  326. */
  327. public QueryThread(DBUtil dbUtil) {
  328. this.dbUtil = dbUtil;
  329. }
  330. public void run() {
  331. while (true) {
  332. try {
  333. if (startQuery) {
  334. this.dbUtil.query("select 1");
  335. }
  336. // System.out.println(startQuery+"   123");
  337. } catch (Exception e) {
  338. e.printStackTrace();
  339. } finally {
  340. try {
  341. Thread.sleep(120000);
  342. } catch (InterruptedException e) {
  343. e.printStackTrace();
  344. }
  345. }
  346. }
  347. }
  348. public void setStartQuery(boolean startQuery) {
  349. // System.out.println("startQuery shut:"+startQuery);
  350. this.startQuery = startQuery;
  351. }
  352. }

二、DES加密和解密

  1. package com.itjh.javaUtil;
  2. import java.io.UnsupportedEncodingException;
  3. import java.security.InvalidKeyException;
  4. import java.security.NoSuchAlgorithmException;
  5. import java.security.SecureRandom;
  6. import java.security.spec.InvalidKeySpecException;
  7. import javax.crypto.BadPaddingException;
  8. import javax.crypto.Cipher;
  9. import javax.crypto.IllegalBlockSizeException;
  10. import javax.crypto.KeyGenerator;
  11. import javax.crypto.NoSuchPaddingException;
  12. import javax.crypto.SecretKey;
  13. import javax.crypto.SecretKeyFactory;
  14. import javax.crypto.spec.DESKeySpec;
  15. /**
  16. * DES加密和解密。
  17. *
  18. * @author 宋立君
  19. * @date 2014年07月03日
  20. */
  21. public class DESUtil {
  22. /** 安全密钥 */
  23. private String keyData = "ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstwxyz0123456789-_.";
  24. /**
  25. * 功能:构造
  26. *
  27. * @author 宋立君
  28. * @date 2014年07月03日
  29. */
  30. public DESUtil() {
  31. }
  32. /**
  33. * 功能:构造
  34. *
  35. * @author 宋立君
  36. * @date 2014年07月03日
  37. * @param keyData
  38. *            key
  39. */
  40. public DESUtil(String key) {
  41. this.keyData = key;
  42. }
  43. /**
  44. * 功能:加密 (UTF-8)
  45. *
  46. * @author 宋立君
  47. * @date 2014年07月03日
  48. * @param source
  49. *            源字符串
  50. * @param charSet
  51. *            编码
  52. * @return String
  53. * @throws UnsupportedEncodingException
  54. *             编码异常
  55. */
  56. public String encrypt(String source) throws UnsupportedEncodingException {
  57. return encrypt(source, "UTF-8");
  58. }
  59. /**
  60. *
  61. * 功能:解密 (UTF-8)
  62. *
  63. * @author 宋立君
  64. * @date 2014年07月03日
  65. * @param encryptedData
  66. *            被加密后的字符串
  67. * @return String
  68. * @throws UnsupportedEncodingException
  69. *             编码异常
  70. */
  71. public String decrypt(String encryptedData)
  72. throws UnsupportedEncodingException {
  73. return decrypt(encryptedData, "UTF-8");
  74. }
  75. /**
  76. * 功能:加密
  77. *
  78. * @author 宋立君
  79. * @date 2014年07月03日
  80. * @param source
  81. *            源字符串
  82. * @param charSet
  83. *            编码
  84. * @return String
  85. * @throws UnsupportedEncodingException
  86. *             编码异常
  87. */
  88. public String encrypt(String source, String charSet)
  89. throws UnsupportedEncodingException {
  90. String encrypt = null;
  91. byte[] ret = encrypt(source.getBytes(charSet));
  92. encrypt = new String(Base64.encode(ret));
  93. return encrypt;
  94. }
  95. /**
  96. *
  97. * 功能:解密
  98. *
  99. * @author 宋立君
  100. * @date 2014年07月03日
  101. * @param encryptedData
  102. *            被加密后的字符串
  103. * @param charSet
  104. *            编码
  105. * @return String
  106. * @throws UnsupportedEncodingException
  107. *             编码异常
  108. */
  109. public String decrypt(String encryptedData, String charSet)
  110. throws UnsupportedEncodingException {
  111. String descryptedData = null;
  112. byte[] ret = descrypt(Base64.decode(encryptedData.toCharArray()));
  113. descryptedData = new String(ret, charSet);
  114. return descryptedData;
  115. }
  116. /**
  117. * 加密数据 用生成的密钥加密原始数据
  118. *
  119. * @param primaryData
  120. *            原始数据
  121. * @return byte[]
  122. * @author 宋立君
  123. * @date 2014年07月03日
  124. */
  125. private byte[] encrypt(byte[] primaryData) {
  126. /** 取得安全密钥 */
  127. byte rawKeyData[] = getKey();
  128. /** DES算法要求有一个可信任的随机数源 */
  129. SecureRandom sr = new SecureRandom();
  130. /** 使用原始密钥数据创建DESKeySpec对象 */
  131. DESKeySpec dks = null;
  132. try {
  133. dks = new DESKeySpec(keyData.getBytes());
  134. } catch (InvalidKeyException e) {
  135. e.printStackTrace();
  136. }
  137. /** 创建一个密钥工厂 */
  138. SecretKeyFactory keyFactory = null;
  139. try {
  140. keyFactory = SecretKeyFactory.getInstance("DES");
  141. } catch (NoSuchAlgorithmException e) {
  142. e.printStackTrace();
  143. }
  144. /** 用密钥工厂把DESKeySpec转换成一个SecretKey对象 */
  145. SecretKey key = null;
  146. try {
  147. key = keyFactory.generateSecret(dks);
  148. } catch (InvalidKeySpecException e) {
  149. e.printStackTrace();
  150. }
  151. /** Cipher对象实际完成加密操作 */
  152. Cipher cipher = null;
  153. try {
  154. cipher = Cipher.getInstance("DES");
  155. } catch (NoSuchAlgorithmException e) {
  156. e.printStackTrace();
  157. } catch (NoSuchPaddingException e) {
  158. e.printStackTrace();
  159. }
  160. /** 用密钥初始化Cipher对象 */
  161. try {
  162. cipher.init(Cipher.ENCRYPT_MODE, key, sr);
  163. } catch (InvalidKeyException e) {
  164. e.printStackTrace();
  165. }
  166. /** 正式执行加密操作 */
  167. byte encryptedData[] = null;
  168. try {
  169. encryptedData = cipher.doFinal(primaryData);
  170. } catch (IllegalStateException e) {
  171. e.printStackTrace();
  172. } catch (IllegalBlockSizeException e) {
  173. e.printStackTrace();
  174. } catch (BadPaddingException e) {
  175. e.printStackTrace();
  176. }
  177. /** 返回加密数据 */
  178. return encryptedData;
  179. }
  180. /**
  181. * 用密钥解密数据
  182. *
  183. * @param encryptedData
  184. *            加密后的数据
  185. * @return byte[]
  186. * @author 宋立君
  187. * @date 2014年07月03日
  188. */
  189. private byte[] descrypt(byte[] encryptedData) {
  190. /** DES算法要求有一个可信任的随机数源 */
  191. SecureRandom sr = new SecureRandom();
  192. /** 取得安全密钥 */
  193. byte rawKeyData[] = getKey();
  194. /** 使用原始密钥数据创建DESKeySpec对象 */
  195. DESKeySpec dks = null;
  196. try {
  197. dks = new DESKeySpec(keyData.getBytes());
  198. } catch (InvalidKeyException e) {
  199. e.printStackTrace();
  200. }
  201. /** 创建一个密钥工厂 */
  202. SecretKeyFactory keyFactory = null;
  203. try {
  204. keyFactory = SecretKeyFactory.getInstance("DES");
  205. } catch (NoSuchAlgorithmException e) {
  206. e.printStackTrace();
  207. }
  208. /** 用密钥工厂把DESKeySpec转换成一个SecretKey对象 */
  209. SecretKey key = null;
  210. try {
  211. key = keyFactory.generateSecret(dks);
  212. } catch (InvalidKeySpecException e) {
  213. e.printStackTrace();
  214. }
  215. /** Cipher对象实际完成加密操作 */
  216. Cipher cipher = null;
  217. try {
  218. cipher = Cipher.getInstance("DES");
  219. } catch (NoSuchAlgorithmException e) {
  220. e.printStackTrace();
  221. } catch (NoSuchPaddingException e) {
  222. e.printStackTrace();
  223. }
  224. /** 用密钥初始化Cipher对象 */
  225. try {
  226. cipher.init(Cipher.DECRYPT_MODE, key, sr);
  227. } catch (InvalidKeyException e) {
  228. e.printStackTrace();
  229. }
  230. /** 正式执行解密操作 */
  231. byte decryptedData[] = null;
  232. try {
  233. decryptedData = cipher.doFinal(encryptedData);
  234. } catch (IllegalStateException e) {
  235. e.printStackTrace();
  236. } catch (IllegalBlockSizeException e) {
  237. e.printStackTrace();
  238. } catch (BadPaddingException e) {
  239. e.printStackTrace();
  240. }
  241. return decryptedData;
  242. }
  243. /**
  244. * 取得安全密钥 此方法作废,因为每次key生成都不一样导致解密加密用的密钥都不一样, 从而导致Given final block not
  245. * properly padded错误.
  246. *
  247. * @return byte数组
  248. * @author 宋立君
  249. * @date 2014年07月03日
  250. */
  251. private byte[] getKey() {
  252. /** DES算法要求有一个可信任的随机数源 */
  253. SecureRandom sr = new SecureRandom();
  254. /** 为我们选择的DES算法生成一个密钥生成器对象 */
  255. KeyGenerator kg = null;
  256. try {
  257. kg = KeyGenerator.getInstance("DES");
  258. } catch (NoSuchAlgorithmException e) {
  259. e.printStackTrace();
  260. }
  261. kg.init(sr);
  262. /** 生成密钥工具类 */
  263. SecretKey key = kg.generateKey();
  264. /** 生成密钥byte数组 */
  265. byte rawKeyData[] = key.getEncoded();
  266. return rawKeyData;
  267. }
  268. }

Base64.java

  1. package com.itjh.javaUtil;
  2. import java.io.*;
  3. /**
  4. * Base64 编码和解码。
  5. *
  6. * @author 宋立君
  7. * @date 2014年07月03日
  8. */
  9. public class Base64 {
  10. public Base64() {
  11. }
  12. /**
  13. * 功能:编码字符串
  14. *
  15. * @author 宋立君
  16. * @date 2014年07月03日
  17. * @param data
  18. *            源字符串
  19. * @return String
  20. */
  21. public static String encode(String data) {
  22. return new String(encode(data.getBytes()));
  23. }
  24. /**
  25. * 功能:解码字符串
  26. *
  27. * @author 宋立君
  28. * @date 2014年07月03日
  29. * @param data
  30. *            源字符串
  31. * @return String
  32. */
  33. public static String decode(String data) {
  34. return new String(decode(data.toCharArray()));
  35. }
  36. /**
  37. * 功能:编码byte[]
  38. *
  39. * @author 宋立君
  40. * @date 2014年07月03日
  41. * @param data
  42. *            源
  43. * @return char[]
  44. */
  45. public static char[] encode(byte[] data) {
  46. char[] out = new char[((data.length + 2) / 3) * 4];
  47. for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
  48. boolean quad = false;
  49. boolean trip = false;
  50. int val = (0xFF & (int) data[i]);
  51. val <<= 8;
  52. if ((i + 1) < data.length) {
  53. val |= (0xFF & (int) data[i + 1]);
  54. trip = true;
  55. }
  56. val <<= 8;
  57. if ((i + 2) < data.length) {
  58. val |= (0xFF & (int) data[i + 2]);
  59. quad = true;
  60. }
  61. out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
  62. val >>= 6;
  63. out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
  64. val >>= 6;
  65. out[index + 1] = alphabet[val & 0x3F];
  66. val >>= 6;
  67. out[index + 0] = alphabet[val & 0x3F];
  68. }
  69. return out;
  70. }
  71. /**
  72. * 功能:解码
  73. *
  74. * @author 宋立君
  75. * @date 2014年07月03日
  76. * @param data
  77. *            编码后的字符数组
  78. * @return byte[]
  79. */
  80. public static byte[] decode(char[] data) {
  81. int tempLen = data.length;
  82. for (int ix = 0; ix < data.length; ix++) {
  83. if ((data[ix] > 255) || codes[data[ix]] < 0) {
  84. --tempLen; // ignore non-valid chars and padding
  85. }
  86. }
  87. // calculate required length:
  88. // -- 3 bytes for every 4 valid base64 chars
  89. // -- plus 2 bytes if there are 3 extra base64 chars,
  90. // or plus 1 byte if there are 2 extra.
  91. int len = (tempLen / 4) * 3;
  92. if ((tempLen % 4) == 3) {
  93. len += 2;
  94. }
  95. if ((tempLen % 4) == 2) {
  96. len += 1;
  97. }
  98. byte[] out = new byte[len];
  99. int shift = 0; // # of excess bits stored in accum
  100. int accum = 0; // excess bits
  101. int index = 0;
  102. // we now go through the entire array (NOT using the 'tempLen' value)
  103. for (int ix = 0; ix < data.length; ix++) {
  104. int value = (data[ix] > 255) ? -1 : codes[data[ix]];
  105. if (value >= 0) { // skip over non-code
  106. accum <<= 6; // bits shift up by 6 each time thru
  107. shift += 6; // loop, with new bits being put in
  108. accum |= value; // at the bottom.
  109. if (shift >= 8) { // whenever there are 8 or more shifted in,
  110. shift -= 8; // write them out (from the top, leaving any
  111. out[index++] = // excess at the bottom for next iteration.
  112. (byte) ((accum >> shift) & 0xff);
  113. }
  114. }
  115. }
  116. // if there is STILL something wrong we just have to throw up now!
  117. if (index != out.length) {
  118. throw new Error("Miscalculated data length (wrote " + index
  119. + " instead of " + out.length + ")");
  120. }
  121. return out;
  122. }
  123. /**
  124. * 功能:编码文件
  125. *
  126. * @author 宋立君
  127. * @date 2014年07月03日
  128. * @param file
  129. *            源文件
  130. */
  131. public static void encode(File file) throws IOException {
  132. if (!file.exists()) {
  133. System.exit(0);
  134. }
  135. else {
  136. byte[] decoded = readBytes(file);
  137. char[] encoded = encode(decoded);
  138. writeChars(file, encoded);
  139. }
  140. file = null;
  141. }
  142. /**
  143. * 功能:解码文件。
  144. *
  145. * @author 宋立君
  146. * @date 2014年07月03日
  147. * @param file
  148. *            源文件
  149. * @throws IOException
  150. */
  151. public static void decode(File file) throws IOException {
  152. if (!file.exists()) {
  153. System.exit(0);
  154. } else {
  155. char[] encoded = readChars(file);
  156. byte[] decoded = decode(encoded);
  157. writeBytes(file, decoded);
  158. }
  159. file = null;
  160. }
  161. //
  162. // code characters for values 0..63
  163. //
  164. private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
  165. .toCharArray();
  166. //
  167. // lookup table for converting base64 characters to value in range 0..63
  168. //
  169. private static byte[] codes = new byte[256];
  170. static {
  171. for (int i = 0; i < 256; i++) {
  172. codes[i] = -1;
  173. // LoggerUtil.debug(i + "&" + codes[i] + " ");
  174. }
  175. for (int i = 'A'; i <= 'Z'; i++) {
  176. codes[i] = (byte) (i - 'A');
  177. // LoggerUtil.debug(i + "&" + codes[i] + " ");
  178. }
  179. for (int i = 'a'; i <= 'z'; i++) {
  180. codes[i] = (byte) (26 + i - 'a');
  181. // LoggerUtil.debug(i + "&" + codes[i] + " ");
  182. }
  183. for (int i = '0'; i <= '9'; i++) {
  184. codes[i] = (byte) (52 + i - '0');
  185. // LoggerUtil.debug(i + "&" + codes[i] + " ");
  186. }
  187. codes['+'] = 62;
  188. codes['/'] = 63;
  189. }
  190. private static byte[] readBytes(File file) throws IOException {
  191. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  192. byte[] b = null;
  193. InputStream fis = null;
  194. InputStream is = null;
  195. try {
  196. fis = new FileInputStream(file);
  197. is = new BufferedInputStream(fis);
  198. int count = 0;
  199. byte[] buf = new byte[16384];
  200. while ((count = is.read(buf)) != -1) {
  201. if (count > 0) {
  202. baos.write(buf, 0, count);
  203. }
  204. }
  205. b = baos.toByteArray();
  206. } finally {
  207. try {
  208. if (fis != null)
  209. fis.close();
  210. if (is != null)
  211. is.close();
  212. if (baos != null)
  213. baos.close();
  214. } catch (Exception e) {
  215. System.out.println(e);
  216. }
  217. }
  218. return b;
  219. }
  220. private static char[] readChars(File file) throws IOException {
  221. CharArrayWriter caw = new CharArrayWriter();
  222. Reader fr = null;
  223. Reader in = null;
  224. try {
  225. fr = new FileReader(file);
  226. in = new BufferedReader(fr);
  227. int count = 0;
  228. char[] buf = new char[16384];
  229. while ((count = in.read(buf)) != -1) {
  230. if (count > 0) {
  231. caw.write(buf, 0, count);
  232. }
  233. }
  234. } finally {
  235. try {
  236. if (caw != null)
  237. caw.close();
  238. if (in != null)
  239. in.close();
  240. if (fr != null)
  241. fr.close();
  242. } catch (Exception e) {
  243. System.out.println(e);
  244. }
  245. }
  246. return caw.toCharArray();
  247. }
  248. private static void writeBytes(File file, byte[] data) throws IOException {
  249. OutputStream fos = null;
  250. OutputStream os = null;
  251. try {
  252. fos = new FileOutputStream(file);
  253. os = new BufferedOutputStream(fos);
  254. os.write(data);
  255. } finally {
  256. try {
  257. if (os != null)
  258. os.close();
  259. if (fos != null)
  260. fos.close();
  261. } catch (Exception e) {
  262. System.out.println(e);
  263. }
  264. }
  265. }
  266. private static void writeChars(File file, char[] data) throws IOException {
  267. Writer fos = null;
  268. Writer os = null;
  269. try {
  270. fos = new FileWriter(file);
  271. os = new BufferedWriter(fos);
  272. os.write(data);
  273. } finally {
  274. try {
  275. if (os != null)
  276. os.close();
  277. if (fos != null)
  278. fos.close();
  279. } catch (Exception e) {
  280. e.printStackTrace();
  281. }
  282. }
  283. }
  284. // /////////////////////////////////////////////////
  285. // end of test code.
  286. // /////////////////////////////////////////////////
  287. }

三、ExcelUtil工具类

  1. package com.itjh.javaUtil;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.OutputStream;
  8. import java.text.DecimalFormat;
  9. import java.util.LinkedList;
  10. import java.util.List;
  11. import javax.servlet.http.HttpServletResponse;
  12. import org.apache.poi.hssf.usermodel.HSSFCell;
  13. import org.apache.poi.hssf.usermodel.HSSFRichTextString;
  14. import org.apache.poi.hssf.usermodel.HSSFRow;
  15. import org.apache.poi.hssf.usermodel.HSSFSheet;
  16. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  17. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  18. import org.apache.poi.ss.usermodel.Cell;
  19. import org.apache.poi.ss.usermodel.DateUtil;
  20. import org.apache.poi.ss.usermodel.Row;
  21. import org.apache.poi.ss.usermodel.Sheet;
  22. import org.apache.poi.ss.usermodel.Workbook;
  23. import org.apache.poi.ss.usermodel.WorkbookFactory;
  24. /**
  25. * 封装对excel的操作,包括本地读写excel和流中输出excel,支持office 2007。<br/>
  26. * 依赖于poi-3.9-20121203.jar,poi-ooxml-3.9-20121203.jar,poi-ooxml-schemas-3.9-
  27. * 20121203.jar,dom4j-1.6.1.jar<br/>
  28. * 有参构造函数参数为excel的全路径<br/>
  29. *
  30. * @author 宋立君
  31. * @date 2014年07月03日
  32. */
  33. public class ExcelUtil {
  34. // excel文件路径
  35. private String path = "";
  36. // 写入excel时,是否自动扩展列宽度来符合内容。
  37. private boolean autoColumnWidth = false;
  38. /**
  39. * 无参构造函数 默认
  40. */
  41. public ExcelUtil() {
  42. }
  43. /**
  44. * 有参构造函数
  45. *
  46. * @param path
  47. *            excel路径
  48. */
  49. public ExcelUtil(String path) {
  50. this.path = path;
  51. }
  52. /**
  53. * 读取某个工作簿上的所有单元格的值。
  54. *
  55. * @param sheetOrder
  56. *            工作簿序号,从0开始。
  57. * @return List<Object[]> 所有单元格的值。
  58. * @throws IOException
  59. *             加载excel文件IO异常。
  60. * @throws FileNotFoundException
  61. *             excel文件没有找到异常。
  62. * @throws InvalidFormatException
  63. * @author 宋立君
  64. * @date 2014年07月03日
  65. */
  66. public List<Object[]> read(int sheetOrder) throws FileNotFoundException,
  67. IOException, InvalidFormatException {
  68. FileInputStream fis = new FileInputStream(path);
  69. Workbook workbook = WorkbookFactory.create(fis);
  70. if (fis != null) {
  71. fis.close();
  72. }
  73. Sheet sheet = workbook.getSheetAt(sheetOrder);
  74. // 用来记录excel值
  75. List<Object[]> valueList = new LinkedList<Object[]>();
  76. // 循环遍历每一行、每一列。
  77. for (Row row : sheet) {
  78. // 每一行
  79. Object[] rowObject = null;
  80. for (Cell cell : row) {
  81. // cell.getCellType是获得cell里面保存的值的type
  82. switch (cell.getCellType()) {
  83. case Cell.CELL_TYPE_BOOLEAN:
  84. // 得到Boolean对象的方法
  85. rowObject = CollectionUtil.addObjectToArray(rowObject,
  86. cell.getBooleanCellValue());
  87. break;
  88. case Cell.CELL_TYPE_NUMERIC:
  89. // 先看是否是日期格式
  90. if (DateUtil.isCellDateFormatted(cell)) {
  91. // 读取日期格式
  92. rowObject = CollectionUtil.addObjectToArray(rowObject,
  93. cell.getDateCellValue());
  94. } else {
  95. DecimalFormat df = new DecimalFormat();
  96. // 单元格的值,替换掉,
  97. String value = df.format(cell.getNumericCellValue())
  98. .replace(",", "");
  99. // 读取数字
  100. rowObject = CollectionUtil.addObjectToArray(rowObject,
  101. value);
  102. }
  103. break;
  104. case Cell.CELL_TYPE_FORMULA:
  105. // 读取公式
  106. rowObject = CollectionUtil.addObjectToArray(rowObject,
  107. cell.getCellFormula());
  108. break;
  109. case Cell.CELL_TYPE_STRING:
  110. // 读取String
  111. rowObject = CollectionUtil.addObjectToArray(rowObject, cell
  112. .getRichStringCellValue().toString());
  113. break;
  114. }
  115. }
  116. // 将这行添加到list。
  117. valueList.add(rowObject);
  118. }
  119. return valueList;
  120. }
  121. /**
  122. * 读取某个工作簿上的某个单元格的值。
  123. *
  124. * @param sheetOrder
  125. *            工作簿序号,从0开始。
  126. * @param colum
  127. *            列数 从1开始
  128. * @param row
  129. *            行数 从1开始
  130. * @return 单元格的值。
  131. * @throws Exception
  132. *             加载excel异常。
  133. * @author 宋立君
  134. * @date 2014年07月03日
  135. */
  136. public String read(int sheetOrder, int colum, int row) throws Exception {
  137. FileInputStream fis = new FileInputStream(path);
  138. Workbook workbook = WorkbookFactory.create(fis);
  139. if (fis != null) {
  140. fis.close();
  141. }
  142. Sheet sheet = workbook.getSheetAt(sheetOrder);
  143. Row rows = sheet.getRow(row - 1);
  144. Cell cell = rows.getCell(colum - 1);
  145. String content = cell.getStringCellValue();
  146. return content;
  147. }
  148. /**
  149. * 在指定的工作簿、行、列书写值。
  150. *
  151. * @param sheetOrder
  152. *            工作簿序号,基于0.
  153. * @param colum
  154. *            列 基于1
  155. * @param row
  156. *            行 基于1
  157. * @param content
  158. *            将要被书写的内容。
  159. * @throws Exception
  160. *             书写后保存异常。
  161. * @author 宋立君
  162. * @date 2014年07月03日
  163. */
  164. public void write(int sheetOrder, int colum, int row, String content)
  165. throws Exception {
  166. FileInputStream fis = new FileInputStream(path);
  167. Workbook workbook = WorkbookFactory.create(fis);
  168. if (fis != null) {
  169. fis.close();
  170. }
  171. Sheet sheet = workbook.getSheetAt(sheetOrder);
  172. Row rows = sheet.createRow(row - 1);
  173. Cell cell = rows.createCell(colum - 1);
  174. cell.setCellValue(content);
  175. FileOutputStream fileOut = new FileOutputStream(path);
  176. workbook.write(fileOut);
  177. fileOut.close();
  178. }
  179. /**
  180. * 得到一个工作区最后一条记录的序号,相当于这个工作簿共多少行数据。
  181. *
  182. * @param sheetOrder
  183. *            工作区序号
  184. * @return int 序号。
  185. * @throws IOException
  186. *             根据excel路径加载excel异常。
  187. * @throws InvalidFormatException
  188. * @author 宋立君
  189. * @date 2014年07月03日
  190. */
  191. public int getSheetLastRowNum(int sheetOrder) throws IOException,
  192. InvalidFormatException {
  193. FileInputStream fis = new FileInputStream(path);
  194. Workbook workbook = WorkbookFactory.create(fis);
  195. if (fis != null) {
  196. fis.close();
  197. }
  198. Sheet sheet = workbook.getSheetAt(sheetOrder);
  199. return sheet.getLastRowNum();
  200. }
  201. /**
  202. * 在磁盘生成一个含有内容的excel,路径为path属性
  203. *
  204. * @param sheetName
  205. *            导出的sheet名称
  206. * @param fieldName
  207. *            列名数组
  208. * @param data
  209. *            数据组
  210. * @throws IOException
  211. * @author 宋立君
  212. * @date 2014年07月03日
  213. */
  214. public void makeExcel(String sheetName, String[] fieldName,
  215. List<Object[]> data) throws IOException {
  216. // 在内存中生成工作薄
  217. HSSFWorkbook workbook = makeWorkBook(sheetName, fieldName, data);
  218. // 截取文件夹路径
  219. String filePath = path.substring(0, path.lastIndexOf("\\"));
  220. // 如果路径不存在,创建路径
  221. File file = new File(filePath);
  222. // System.out.println(path+"-----------"+file.exists());
  223. if (!file.exists())
  224. file.mkdirs();
  225. FileOutputStream fileOut = new FileOutputStream(path);
  226. workbook.write(fileOut);
  227. fileOut.close();
  228. }
  229. /**
  230. * 在输出流中导出excel。
  231. *
  232. * @param excelName
  233. *            导出的excel名称 包括扩展名
  234. * @param sheetName
  235. *            导出的sheet名称
  236. * @param fieldName
  237. *            列名数组
  238. * @param data
  239. *            数据组
  240. * @param response
  241. *            response
  242. * @throws IOException
  243. *             转换流时IO错误
  244. * @author 宋立君
  245. * @date 2014年07月03日
  246. */
  247. public void makeStreamExcel(String excelName, String sheetName,
  248. String[] fieldName, List<Object[]> data,
  249. HttpServletResponse response) throws IOException {
  250. OutputStream os = null;
  251. response.reset(); // 清空输出流
  252. os = response.getOutputStream(); // 取得输出流
  253. response.setHeader("Content-disposition", "attachment; filename="
  254. + new String(excelName.getBytes(), "ISO-8859-1")); // 设定输出文件头
  255. response.setContentType("application/msexcel"); // 定义输出类型
  256. // 在内存中生成工作薄
  257. HSSFWorkbook workbook = makeWorkBook(sheetName, fieldName, data);
  258. os.flush();
  259. workbook.write(os);
  260. }
  261. /**
  262. * 根据条件,生成工作薄对象到内存。
  263. *
  264. * @param sheetName
  265. *            工作表对象名称
  266. * @param fieldName
  267. *            首列列名称
  268. * @param data
  269. *            数据
  270. * @return HSSFWorkbook
  271. * @author 宋立君
  272. * @date 2014年07月03日
  273. */
  274. private HSSFWorkbook makeWorkBook(String sheetName, String[] fieldName,
  275. List<Object[]> data) {
  276. // 用来记录最大列宽,自动调整列宽。
  277. Integer collength[] = new Integer[fieldName.length];
  278. // 产生工作薄对象
  279. HSSFWorkbook workbook = new HSSFWorkbook();
  280. // 产生工作表对象
  281. HSSFSheet sheet = workbook.createSheet();
  282. // 为了工作表能支持中文,设置字符集为UTF_16
  283. workbook.setSheetName(0, sheetName);
  284. // 产生一行
  285. HSSFRow row = sheet.createRow(0);
  286. // 产生单元格
  287. HSSFCell cell;
  288. // 写入各个字段的名称
  289. for (int i = 0; i < fieldName.length; i++) {
  290. // 创建第一行各个字段名称的单元格
  291. cell = row.createCell((short) i);
  292. // 设置单元格内容为字符串型
  293. cell.setCellType(HSSFCell.CELL_TYPE_STRING);
  294. // 为了能在单元格中输入中文,设置字符集为UTF_16
  295. // cell.setEncoding(HSSFCell.ENCODING_UTF_16);
  296. // 给单元格内容赋值
  297. cell.setCellValue(new HSSFRichTextString(fieldName[i]));
  298. // 初始化列宽
  299. collength[i] = fieldName[i].getBytes().length;
  300. }
  301. // 临时单元格内容
  302. String tempCellContent = "";
  303. // 写入各条记录,每条记录对应excel表中的一行
  304. for (int i = 0; i < data.size(); i++) {
  305. Object[] tmp = data.get(i);
  306. // 生成一行
  307. row = sheet.createRow(i + 1);
  308. for (int j = 0; j < tmp.length; j++) {
  309. cell = row.createCell((short) j);
  310. // 设置单元格字符类型为String
  311. cell.setCellType(HSSFCell.CELL_TYPE_STRING);
  312. tempCellContent = (tmp[j] == null) ? "" : tmp[j].toString();
  313. cell.setCellValue(new HSSFRichTextString(tempCellContent));
  314. // 如果自动调整列宽度。
  315. if (autoColumnWidth) {
  316. if (j >= collength.length) { // 标题列数小于数据列数时。
  317. collength = CollectionUtil.addObjectToArray(collength,
  318. tempCellContent.getBytes().length);
  319. } else {
  320. // 如果这个内容的宽度大于之前最大的,就按照这个设置宽度。
  321. if (collength[j] < tempCellContent.getBytes().length) {
  322. collength[j] = tempCellContent.getBytes().length;
  323. }
  324. }
  325. }
  326. }
  327. }
  328. // 自动调整列宽度。
  329. if (autoColumnWidth) {
  330. // 调整列为这列文字对应的最大宽度。
  331. for (int i = 0; i < fieldName.length; i++) {
  332. sheet.setColumnWidth(i, collength[i] * 2 * 256);
  333. }
  334. }
  335. return workbook;
  336. }
  337. /**
  338. * 功能:设置写入excel时,是否自动扩展列宽度来符合内容,默认为false。
  339. *
  340. * @author 宋立君
  341. * @date 2014年07月03日
  342. * @param autoColumnWidth
  343. *            true或者false
  344. */
  345. public void setAutoColumnWidth(boolean autoColumnWidth) {
  346. this.autoColumnWidth = autoColumnWidth;
  347. }
  348. }