java 常用工具类的使用<四>

一、连接数据库的综合类

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

二、DES加密和解密

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

Base64.java

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

三、ExcelUtil工具类

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