import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import jxl.Workbook;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
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.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
public class ExcelUtils {
/**
* 讀取excel文件 添加到數據庫 小批量插入 低於2萬條
* @since 1.0
* @param big 是否是大數據插入只適用於2007版本的Excel
* @param size 多少條數據插入一次
* @param excelUrl 文件地址
* @param tableName 表明
* @param primaryKey 主鍵
* @param attrs 屬性
* @return
* @throws IOException
* <br><b>作者: @author WangDong</b>
* <br>創建時間:2017-12-29 上午11:44:01
*/
@Before({Tx.class})
public static Record readExcelToSql(Boolean big ,Integer size,String excelUrl,String tableName,String primaryKey,Object[] attrs)
throws IOException ,SQLException{
long starTime=System.currentTimeMillis();
int saveCount = 0;
int count = 0;
boolean flag = false;
Record record = new Record();
String suffix = excelUrl.substring(excelUrl.lastIndexOf(".") + 1)
.trim();
StringBuffer into = new StringBuffer("insert into "+tableName+" (");
into.append(primaryKey);
for (int i = 0; i < attrs.length; i++) {
into.append(",");
into.append(attrs[i]);
}
into.append(") values ");
StringBuffer values = new StringBuffer();
List<Object> parms = new ArrayList<Object>();
try {
if (CommCode.EXCEL_SUFFIX_XLS.equals(suffix)) {
// 2003
InputStream in = new FileInputStream(excelUrl);
HSSFWorkbook workbook = new HSSFWorkbook(in);
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
HSSFSheet sheet = workbook.getSheetAt(i);
if (null == sheet)
continue;
int lastRowNum = sheet.getLastRowNum();
for (int j = 0; j <= lastRowNum; j++) {
HSSFRow row = sheet.getRow(j);
if (null == row) {
continue;
}
if(j != 0 && flag){
values.append(",");
}
values.append("(?");
parms.add(UUID.randomUUID().toString());
for (int a = 0; a < attrs.length; a++) {
values.append(",");
HSSFCell cell = row.getCell(a);
cell.setCellType(Cell.CELL_TYPE_STRING);
values.append("?");
parms.add(StringUtils.isNotBlank(cell.getStringCellValue())?cell.getStringCellValue():null);
flag = true;
}
values.append(")");
count ++;
if(count % size == 0){
int upateMySQL = insertMySQL(into.toString()+values.toString(), parms);
saveCount += upateMySQL;
parms.clear();
values.setLength(0);
flag = false;
}
if(j == lastRowNum && (lastRowNum+1) % size != 0){
int upateMySQL = insertMySQL(into.toString()+values.toString(), parms);
saveCount += upateMySQL;
parms.clear();
values.setLength(0);
flag = false;
}
}
}
long endTime=System.currentTimeMillis();
long time=endTime-starTime;
if(saveCount != count){
record.set("state", false);
record.set("msg", "插入數據出現異常,成功條數與文件條數不一致,相差"+(count-saveCount)+"條!");
}else{
record.set("state", true);
record.set("msg", "成功插入"+saveCount+"條數據!用時:"+time/1000+"秒");
}
} else if (CommCode.EXCEL_SUFFIX_XLSX.equals(suffix)) {
if(big){
return readBigExcelToSql(size, excelUrl, tableName, primaryKey, attrs);
}
// 2007
// OPCPackage pkg = OPCPackage.open(filename);
InputStream in = new FileInputStream(excelUrl);
XSSFWorkbook workbook = new XSSFWorkbook(in);
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
XSSFSheet sheet = workbook.getSheetAt(i);
if (null == sheet)
continue;
int lastRowNum = sheet.getLastRowNum();
for (int j = 0; j <= lastRowNum; j++) {
XSSFRow row = sheet.getRow(j);
if (null == row) {
continue;
}
if(j != 0 && flag){
values.append(",");
}
values.append("(?");
parms.add(UUID.randomUUID().toString());
for (int a = 0; a < attrs.length; a++) {
values.append(",");
XSSFCell cell = row.getCell(a);
cell.setCellType(Cell.CELL_TYPE_STRING);
values.append("?");
parms.add(StringUtils.isNotBlank(cell.getStringCellValue())?cell.getStringCellValue():null);
flag = true;
}
values.append(")");
count ++;
if(count % size == 0){
int upateMySQL = insertMySQL(into.toString()+values.toString(), parms);
saveCount += upateMySQL;
parms.clear();
values.setLength(0);
flag = false;
}
if(j == lastRowNum && (lastRowNum+1) % size != 0){
int upateMySQL = insertMySQL(into.toString()+values.toString(), parms);
saveCount += upateMySQL;
parms.clear();
values.setLength(0);
flag = false;
}
}
}
long endTime=System.currentTimeMillis();
long time=endTime-starTime;
if(saveCount != count){
record.set("state", false);
record.set("msg", "插入數據出現異常,成功條數與文件條數不一致,相差"+(count-saveCount)+"條!");
}else{
record.set("state", true);
record.set("msg", "成功插入"+saveCount+"條數據!用時:"+time/1000+"秒");
}
}else{
record.set("state", false);
record.set("msg", "您選擇的Excel版本不是2003版或2007版,或者不是Excel文件!");
}
} catch (Exception e) {
record.set("state", false);
record.set("msg", "插入數據過程中出現系統異常!請聯繫系統人員!!!");
}
return record;
}
/**
* 讀取excel文件 添加到數據庫
* @since 1.0
* @param size 多少條數據插入一次
* @param excelUrl 文件地址
* @param tableName 表明
* @param primaryKey 主鍵
* @param attrs 屬性
* @return
* @throws Exception
*/
@Before({Tx.class})
public static Record readBigExcelToSql(final Integer size,String excelUrl,String tableName,final String primaryKey,final Object[] attrs)
throws Exception ,SQLException{
final long starTime=System.currentTimeMillis();
int saveCount = 0;
int count = 0;
final Record record = new Record();
boolean flag = false;
final StringBuffer into = new StringBuffer("insert into "+tableName+" (");
into.append(primaryKey);
for (int i = 0; i < attrs.length; i++) {
into.append(",");
into.append(attrs[i]);
}
into.append(") values ");
StringBuffer values = new StringBuffer();
List<Object> parms = new ArrayList<Object>();
final BigExcelReader excel2007 = new BigExcelReader(excelUrl) {
@Override
protected void outputRow(String[] datas, int[] rowTypes, int rowIndex) {
Record data = new Record();
for (int i = 0; i<datas.length;i++) {
data.set(primaryKey, UUID.randomUUID().toString());
data.set(attrs[i].toString(), datas[i]);
}
list.add(data);
}
};
// 執行解析
excel2007.parse();
try {
//int[] batchSave = Db.batchSave(tableName, BigExcelReader.list, size);
for (int i = 0; i < BigExcelReader.list.size(); i++) {
if (null == BigExcelReader.list.get(i)) {
continue;
}
if(i != 0 && flag){
values.append(",");
}
values.append("(?");
parms.add(BigExcelReader.list.get(i).get(primaryKey));
for (int j = 0; j < attrs.length; j++) {
values.append(",?");
parms.add(BigExcelReader.list.get(i).get(attrs[j].toString()));
}
values.append(")");
count ++;
flag = true;
if(count % size == 0 && count != BigExcelReader.list.size()){
int upateMySQL = insertMySQL(into.toString()+values.toString(), parms);
saveCount += upateMySQL;
parms.clear();
values.setLength(0);
flag = false;
}
if(count % size != 0 && count == BigExcelReader.list.size()){
int upateMySQL = insertMySQL(into.toString()+values.toString(), parms);
saveCount += upateMySQL;
parms.clear();
values.setLength(0);
flag = false;
}
}
} catch (Exception e) {
// TODO: handle exception
BigExcelReader.list.clear();
record.set("state", false);
record.set("msg", "插入數據過程中出現系統異常!請聯繫系統人員!!!");
return record;
}
BigExcelReader.list.clear();
long endTime=System.currentTimeMillis();
long time=endTime-starTime;
if(saveCount != count){
record.set("state", false);
record.set("msg", "插入數據出現異常,成功條數與文件條數不一致,相差"+(count-saveCount)+"條!");
}else{
record.set("state", true);
record.set("msg", "成功插入"+saveCount+"條數據!用時:"+time/1000+"秒");
}
return record;
}
/** 插入到數據庫
*
* @since 1.0
* @param sql
* @param parms
* @return
* <br><b>作者: @author WangDong</b>
* <br>創建時間:2017-12-29 下午2:44:19
*/
@Before({Tx.class})
public static int insertMySQL(String sql,List<Object> parms){
return Db.update(sql,parms.toArray());
}
}
package com.jiazheng.utils;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import com.jfinal.plugin.activerecord.Record;
/** 大批量Excel數據讀取 只適用於2007版本
*
* <br>創建日期:2018-1-3
* <br><b>Copyright 2018 DCKEJI All Rights Reserved</b>
* @author WangDong
* @since 1.0
* @version 1.0
*/
public abstract class BigExcelReader{
enum xssfDataType {
BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER,
}
public static final int ERROR = 1;
public static final int BOOLEAN = 1;
public static final int NUMBER = 2;
public static final int STRING = 3;
public static final int DATE = 4;
public static final String DATE_FORMAT_STR = "yyyy-MM-dd HH:mm:ss";
public static List<Record> list = new ArrayList<Record>();
// private DataFormatter formatter = new DataFormatter();
private InputStream sheet;
private XMLReader parser;
private InputSource sheetSource;
private int index = 0;
/**
* 讀大數據量Excel
*
* @param filename 文件名
* @param maxColNum 讀取的最大列數
* @throws IOException
* @throws OpenXML4JException
* @throws SAXException
*/
public BigExcelReader(String filename) throws IOException, OpenXML4JException, SAXException{
OPCPackage pkg = OPCPackage.open(filename);
init(pkg);
}
/**
* 讀大數據量Excel
*
* @param file Excel文件
* @param maxColNum 讀取的最大列數
* @throws IOException
* @throws OpenXML4JException
* @throws SAXException
*/
public BigExcelReader(File file) throws IOException, OpenXML4JException, SAXException{
OPCPackage pkg = OPCPackage.openOrCreate(file);
init(pkg);
}
/**
* 讀大數據量Excel
*
* @param in Excel文件輸入流
* @throws IOException
* @throws OpenXML4JException
* @throws SAXException
*/
public BigExcelReader(InputStream in) throws IOException, OpenXML4JException, SAXException{
OPCPackage pkg = OPCPackage.open(in);
init(pkg);
}
/**
* 初始化 將Excel轉換爲XML
*
* @param pkg
* @throws IOException
* @throws OpenXML4JException
* @throws SAXException
*/
private void init(OPCPackage pkg) throws IOException, OpenXML4JException, SAXException{
XSSFReader xssfReader = new XSSFReader(pkg);
SharedStringsTable sharedStringsTable = xssfReader.getSharedStringsTable();
StylesTable stylesTable = xssfReader.getStylesTable();
sheet = xssfReader.getSheet("rId1");
parser = fetchSheetParser(sharedStringsTable, stylesTable);
sheetSource = new InputSource(sheet);
}
/**
* 執行解析操作
*
* @return 讀取的Excel行數
*/
public int parse(){
try {
parser.parse(sheetSource);
}
catch (IOException e) {
e.printStackTrace();
}
catch (SAXException e) {
e.printStackTrace();
}
finally{
if(sheet != null){
try {
sheet.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return index;
}
private XMLReader fetchSheetParser(SharedStringsTable sharedStringsTable, StylesTable stylesTable) {
XMLReader parser = null;
try {
parser = XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser"
);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ContentHandler handler = new SheetHandler(sharedStringsTable, stylesTable);
parser.setContentHandler(handler);
return parser;
}
/**
* SAX解析的處理類
* 每解析一行數據後通過outputRow(String[] datas, int[] rowTypes, int rowIndex)方法進行輸出
*
* @author zpin
*/
private class SheetHandler extends DefaultHandler {
private SharedStringsTable sharedStringsTable; // 存放映射字符串
private StylesTable stylesTable;// 存放單元格樣式
private String readValue;// 存放讀取值
private xssfDataType dataType;// 單元格類型
private String[] rowDatas;// 存放一行中的所有數據
private int[] rowTypes;// 存放一行中所有數據類型
private int colIdx;// 當前所在列
private short formatIndex;
// private String formatString;// 對數值型的數據直接讀爲數值,不對其格式化,所以隱掉此處
private SheetHandler(SharedStringsTable sst,StylesTable stylesTable) {
this.sharedStringsTable = sst;
this.stylesTable = stylesTable;
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
if(name.equals("c")) {// c > 單元格
colIdx = getColumn(attributes);
String cellType = attributes.getValue("t");
String cellStyle = attributes.getValue("s");
this.dataType = xssfDataType.NUMBER;
if ("b".equals(cellType)){
this.dataType = xssfDataType.BOOL;
}
else if ("e".equals(cellType)){
this.dataType = xssfDataType.ERROR;
}
else if ("inlineStr".equals(cellType)){
this.dataType = xssfDataType.INLINESTR;
}
else if ("s".equals(cellType)){
this.dataType = xssfDataType.SSTINDEX;
}
else if ("str".equals(cellType)){
this.dataType = xssfDataType.FORMULA;
}
else if(cellStyle != null){
int styleIndex = Integer.parseInt(cellStyle);
XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
this.formatIndex = style.getDataFormat();
// this.formatString = style.getDataFormatString();
}
}
// 解析到一行的開始處時,初始化數組
else if(name.equals("row")){
int cols = getColsNum(attributes);// 獲取該行的單元格數
rowDatas = new String[cols];
rowTypes = new int[cols];
}
readValue = "";
}
public void endElement(String uri, String localName, String name)
throws SAXException {
if(name.equals("v")) { // 單元格的值
switch(this.dataType){
case BOOL: {
char first = readValue.charAt(0);
rowDatas[colIdx] = first == '0' ? "FALSE" : "TRUE";
rowTypes[colIdx] = BOOLEAN;
break;
}
case ERROR: {
rowDatas[colIdx] = "ERROR:" + readValue.toString();
rowTypes[colIdx] = ERROR;
break;
}
case INLINESTR: {
rowDatas[colIdx] = new XSSFRichTextString(readValue).toString();
rowTypes[colIdx] = STRING;
break;
}
case SSTINDEX:{
int idx = Integer.parseInt(readValue);
rowDatas[colIdx] = new XSSFRichTextString(sharedStringsTable.getEntryAt(idx)).toString();
rowTypes[colIdx] = STRING;
break;
}
case FORMULA:{
rowDatas[colIdx] = readValue;
rowTypes[colIdx] = STRING;
break;
}
case NUMBER:{
// 判斷是否是日期格式
if (HSSFDateUtil.isADateFormat(formatIndex, readValue)) {
Double d = Double.parseDouble(readValue);
Date date = HSSFDateUtil.getJavaDate(d);
rowDatas[colIdx] = DateFormatUtils.format(date, DATE_FORMAT_STR);
rowTypes[colIdx] = DATE;
}
// else if (formatString != null){
// cellData.value = formatter.formatRawCellContents(Double.parseDouble(cellValue), formatIndex, formatString);
// cellData.dataType = NUMBER;
// }
else{
rowDatas[colIdx] = readValue;
rowTypes[colIdx] = NUMBER;
}
break;
}
}
}
// 當解析的一行的末尾時,輸出數組中的數據
else if(name.equals("row")){
outputRow(rowDatas, rowTypes, index++);
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
readValue += new String(ch, start, length);
}
}
/**
* 輸出每一行的數據
*
* @param datas 數據
* @param rowTypes 數據類型
* @param rowIndex 所在行
*/
protected abstract void outputRow(String[] datas, int[] rowTypes, int rowIndex);
private int getColumn(Attributes attrubuts) {
String name = attrubuts.getValue("r");
int column = -1;
for (int i = 0; i < name.length(); ++i) {
if (Character.isDigit(name.charAt(i))) {
break;
}
int c = name.charAt(i);
column = (column + 1) * 26 + c - 'A';
}
return column;
}
private int getColsNum(Attributes attrubuts){
String spans = attrubuts.getValue("spans");
String cols = spans.substring(spans.indexOf(":") + 1);
return Integer.parseInt(cols);
}
}