Commit abe748d9 authored by hezhen's avatar hezhen

123

parent c7e0a0e8
......@@ -24,6 +24,7 @@
</build>
<properties>
<mapper.version>3.4.0</mapper.version>
<poi.version>3.15</poi.version>
</properties>
<dependencies>
......@@ -125,6 +126,50 @@
<scope>compile</scope>
</dependency>
<!-- excel 组件 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>${poi.version}</version>
<exclusions>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.6.0</version>
<exclusions>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
......
package com.github.wxiaoqi.security.common.util.excel;
import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Excel2003格式解析
*
* @author lipengjun
* @email 939961241@qq.com
* @date 2017年10月28日 13:11:27
*/
public class Excel2003Reader implements HSSFListener {
private int minColumns = -1;
private POIFSFileSystem fs;
/**
* 最后一行行号
*/
private int lastRowNumber;
/**
* 最后一列列号
*/
private int lastColumnNumber;
/**
* Should we output the formula, or the value it has?
*/
private boolean outputFormulaValues = true;
/**
* For parsing Formulas
*/
private SheetRecordCollectingListener workbookBuildingListener;
// 工作薄
private HSSFWorkbook stubWorkbook;
// Records we pick up as we process
private SSTRecord sstRecord;
private FormatTrackingHSSFListener formatListener;
// 表索引
private int sheetIndex = -1;
private BoundSheetRecord[] orderedBSRs;
@SuppressWarnings("rawtypes")
private ArrayList boundSheetRecords = new ArrayList();
// For handling formulas with string results
private int nextRow;
private int nextColumn;
private boolean outputNextStringRecord;
// 存储行记录的容器
private List<String> rowlist = new ArrayList<String>();
;
// 单Sheet数据
private List<String[]> sheetData = new ArrayList<String[]>();
// 多Sheet数据
private Map<Integer, List<String[]>> workData = new HashMap<Integer, List<String[]>>();
/**
* 遍历excel下所有的sheet
*
* @param fileStream 处理文件流
* @throws IOException 抛出IO异常
*/
public void process(InputStream fileStream)
throws IOException {
this.fs = new POIFSFileSystem(fileStream);
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(
this);
formatListener = new FormatTrackingHSSFListener(listener);
HSSFEventFactory factory = new HSSFEventFactory();
HSSFRequest request = new HSSFRequest();
if (outputFormulaValues) {
request.addListenerForAllRecords(formatListener);
} else {
workbookBuildingListener = new SheetRecordCollectingListener(
formatListener);
request.addListenerForAllRecords(workbookBuildingListener);
}
factory.processWorkbookEvents(request, fs);
}
/**
* HSSFListener 监听方法,处理 Record
*
* @param record 行记录
*/
@SuppressWarnings("unchecked")
@Override
public void processRecord(Record record) {
int thisRow = -1;
int thisColumn = -1;
String thisStr = null;
String value = null;
switch (record.getSid()) {
case BoundSheetRecord.sid:
boundSheetRecords.add(record);
break;
case BOFRecord.sid:
BOFRecord br = (BOFRecord) record;
if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
// 如果有需要,则建立子工作薄
if (workbookBuildingListener != null && stubWorkbook == null) {
stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();
}
if (sheetIndex >= 0) {
List<String[]> data = new ArrayList<String[]>();
data.addAll(sheetData);
workData.put(sheetIndex, data);
sheetData.clear();
}
sheetIndex++;
if (orderedBSRs == null) {
orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
}
}
break;
case SSTRecord.sid:
sstRecord = (SSTRecord) record;
break;
case BlankRecord.sid:
BlankRecord brec = (BlankRecord) record;
thisRow = brec.getRow();
thisColumn = brec.getColumn();
thisStr = "";
rowlist.add(thisColumn, thisStr);
break;
case BoolErrRecord.sid: // 单元格为布尔类型
BoolErrRecord berec = (BoolErrRecord) record;
thisRow = berec.getRow();
thisColumn = berec.getColumn();
thisStr = berec.getBooleanValue() + "";
rowlist.add(thisColumn, thisStr);
break;
case FormulaRecord.sid: // 单元格为公式类型
FormulaRecord frec = (FormulaRecord) record;
thisRow = frec.getRow();
thisColumn = frec.getColumn();
if (outputFormulaValues) {
if (Double.isNaN(frec.getValue())) {
// Formula result is a string
// This is stored in the next record
outputNextStringRecord = true;
nextRow = frec.getRow();
nextColumn = frec.getColumn();
} else {
thisStr = formatListener.formatNumberDateCell(frec);
}
} else {
thisStr = '"' + HSSFFormulaParser.toFormulaString(
stubWorkbook, frec.getParsedExpression()) + '"';
}
rowlist.add(thisColumn, thisStr);
break;
case StringRecord.sid:// 单元格中公式的字符串
if (outputNextStringRecord) {
// String for formula
StringRecord srec = (StringRecord) record;
thisStr = srec.getString();
thisRow = nextRow;
thisColumn = nextColumn;
outputNextStringRecord = false;
}
break;
case LabelRecord.sid:
LabelRecord lrec = (LabelRecord) record;
thisColumn = lrec.getColumn();
value = lrec.getValue().trim();
value = value.equals("") ? " " : value;
this.rowlist.add(thisColumn, value);
break;
case LabelSSTRecord.sid: // 单元格为字符串类型
LabelSSTRecord lsrec = (LabelSSTRecord) record;
thisColumn = lsrec.getColumn();
if (sstRecord == null) {
rowlist.add(thisColumn, " ");
} else {
value = sstRecord.getString(lsrec.getSSTIndex()).toString().trim();
value = value.equals("") ? " " : value;
rowlist.add(thisColumn, value);
}
break;
case NumberRecord.sid: // 单元格为数字类型
NumberRecord numrec = (NumberRecord) record;
thisColumn = numrec.getColumn();
value = formatListener.formatNumberDateCell(numrec).trim();
value = value.equals("") ? " " : value;
// 向容器加入列值
rowlist.add(thisColumn, value);
break;
default:
break;
}
// 遇到新行的操作
if (thisRow != -1 && thisRow != lastRowNumber) {
lastColumnNumber = -1;
}
// 空值的操作
if (record instanceof MissingCellDummyRecord) {
MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
thisColumn = mc.getColumn();
rowlist.add(thisColumn, "");
}
// 更新行和列的值
if (thisRow > -1) {
lastRowNumber = thisRow;
}
if (thisColumn > -1) {
lastColumnNumber = thisColumn;
}
// 行结束时的操作
if (record instanceof LastCellOfRowDummyRecord) {
if (minColumns > 0) {
// 列值重新置空
if (lastColumnNumber == -1) {
lastColumnNumber = 0;
}
}
lastColumnNumber = -1;
// 每行结束时, 数据写入集合
sheetData.add(rowlist.toArray(new String[]{}));
// 清空容器
rowlist.clear();
}
}
/**
* 获取数据(单Sheet)
*
* @param sheetIndex sheet下标
* @return List<String[]> 数据
*/
public List<String[]> getSheetData(Integer sheetIndex) {
return workData.get(sheetIndex);
}
/**
* 获取数据(多Sheet)
*
* @return Map<Integer, List<String[]>> 多sheet的数据
*/
public Map<Integer, List<String[]>> getSheetData() {
return workData;
}
}
\ No newline at end of file
package com.github.wxiaoqi.security.common.util.excel;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
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.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Excel2007解析器
*
* @author lipengjun
* @email 939961241@qq.com
* @date 2017年10月28日 13:11:27
*/
public class Excel2007Reader extends DefaultHandler {
/**
* Table with unique strings
*/
private ReadOnlySharedStringsTable sharedStringsTable;
/**
* 总共解析多少列
*/
private final int minColumnCount = 0;
/**
* 判断是否值标签‘V’
*/
private boolean vIsOpen;
/**
* 单元数据类型,startElement中确认赋值,endElement中使用判断
*/
private XssfDataType nextDataType;
/**
* 当前解析列下标
*/
private int thisColumn = -1;
/**
* 已完成解析列最近下标
*/
private int lastColumnNumber = 0;
/**
* 单元格值内容临时存储
*/
private StringBuffer value = new StringBuffer();
/**
* 单行数据集合
*/
private List<String> rowlist = new ArrayList<String>();
/**
* 当前sheet
*/
private int sheetIndex = -1;
/**
* 单Sheet数据
*/
private List<String[]> sheetData = new ArrayList<String[]>();
/**
* 多Sheet数据
*/
private Map<Integer, List<String[]>> workData = new HashMap<Integer, List<String[]>>();
private DataFormatter formatter;
/**
* 格式索引暂时不用
*/
private short formatIndex;
private String formatString;
/**
* 样式表暂时不用
*/
private StylesTable stylesTable;
/**
* 解析单Sheet内容
*
* @param strings 字符串
* @param sheetInputStream 输入流
* @throws IOException IO异常
* @throws ParserConfigurationException 解析异常
* @throws SAXException SAX异常
*/
private void processSheet(ReadOnlySharedStringsTable strings,
InputStream sheetInputStream)
throws IOException, ParserConfigurationException, SAXException {
sheetIndex++;
this.sharedStringsTable = strings;
InputSource sheetSource = new InputSource(sheetInputStream);
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxFactory.newSAXParser();
XMLReader sheetParser = saxParser.getXMLReader();
sheetParser.setContentHandler(this);
sheetParser.parse(sheetSource);
}
/**
* 解析多Sheet内容
* 异常处理暂时不完整
*
* @param fileStream 文件流
* @param isMuti 是否多个sheet
*/
public void process(InputStream fileStream, boolean isMuti) {
OPCPackage xlsxPackage;
try {
xlsxPackage = OPCPackage.open(fileStream);
ReadOnlySharedStringsTable sharedStringsTable = new ReadOnlySharedStringsTable(
xlsxPackage);
XSSFReader xssfReader = new XSSFReader(xlsxPackage);
this.stylesTable = xssfReader.getStylesTable();
this.formatter = new DataFormatter();
XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
while (iter.hasNext()) {
InputStream stream = iter.next();
processSheet(sharedStringsTable, stream);
stream.close();
List<String[]> data = new ArrayList<String[]>();
data.addAll(sheetData);
workData.put(sheetIndex, data);
sheetData.clear();
if (!isMuti) {// 如果只加载一个sheet内容,直接跳出循环
break;
}
}
} catch (InvalidFormatException e) {
throw new RuntimeException("解析EXCEL出错");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("解析EXCEL出错");
} catch (SAXException e) {
e.printStackTrace();
throw new RuntimeException("解析EXCEL出错");
} catch (OpenXML4JException e) {
e.printStackTrace();
throw new RuntimeException("解析EXCEL出错");
} catch (ParserConfigurationException e) {
e.printStackTrace();
throw new RuntimeException("解析EXCEL出错");
}
}
/**
* Receive notification of the start of an element.
* <p>
* <p>By default, do nothing. Application writers may override this
* method in a subclass to take specific actions at the start of
* each element (such as allocating a new tree node or writing
* output to a file).</p>
*
* @param uri The Namespace URI, or the empty string if the
* element has no Namespace URI or if Namespace
* processing is not being performed.
* @param localName The local name (without prefix), or the
* empty string if Namespace processing is not being
* performed.
* @param name The qualified name (with prefix), or the
* empty string if qualified names are not available.
* @param attributes The attributes attached to the element. If
* there are no attributes, it shall be an empty
* Attributes object.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.ContentHandler#startElement
*/
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes)
throws SAXException {
if ("inlineStr".equals(name) || "v".equals(name)) {// v=> value
vIsOpen = true;
value.setLength(0);
} else if ("c".equals(name)) {// c => cell
vIsOpen = false;
String r = attributes.getValue("r");
int firstDigit = -1;
for (int c = 0; c < r.length(); ++c) {
if (Character.isDigit(r.charAt(c))) {
firstDigit = c;
break;
}
}
thisColumn = nameToColumn(r.substring(0, firstDigit));
this.nextDataType = XssfDataType.NUMBER;
String cellType = attributes.getValue("t");
String cellStyleStr = attributes.getValue("s");
if ("b".equals(cellType)) {
nextDataType = XssfDataType.BOOL;
} else if ("e".equals(cellType)) {
nextDataType = XssfDataType.ERROR;
} else if ("inlineStr".equals(cellType)) {
nextDataType = XssfDataType.INLINESTR;
} else if ("s".equals(cellType)) {
nextDataType = XssfDataType.SSTINDEX;
} else if ("str".equals(cellType)) {
nextDataType = XssfDataType.FORMULA;
} else if (cellStyleStr != null) {
// if (cellStyleStr.equals("2")) {// 判断是否是日期
// nextDataType = XssfDataType.DATE;
// }
int styleIndex = Integer.parseInt(cellStyleStr);
XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
this.formatIndex = style.getDataFormat();
this.formatString = style.getDataFormatString();
if (formatIndex == 14 || formatIndex == 15 || formatIndex == 16
|| formatIndex == 17) {
nextDataType = XssfDataType.DATE;
} else if (formatIndex == 18 || formatIndex == 19 || formatIndex == 20
|| formatIndex == 21 || formatIndex == 45 || formatIndex == 46
|| formatIndex == 47) {
nextDataType = XssfDataType.TIME;
} else if (formatIndex == 22) {
nextDataType = XssfDataType.DATETIME;
}
}
}
}
/**
* Receive notification of the end of an element.
* <p>
* <p>By default, do nothing. Application writers may override this
* method in a subclass to take specific actions at the end of
* each element (such as finalising a tree node or writing
* output to a file).</p>
*
* @param uri The Namespace URI, or the empty string if the
* element has no Namespace URI or if Namespace
* processing is not being performed.
* @param localName The local name (without prefix), or the
* empty string if Namespace processing is not being
* performed.
* @param name The qualified name (with prefix), or the
* empty string if qualified names are not available.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.ContentHandler#endElement
*/
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
String thisStr = null;
// v标识单元格值标签
if ("v".equals(name)) {
// Process the value contents as required.
// Do now, as characters() may be called more than once
switch (nextDataType) {
case BOOL:
char first = value.charAt(0);
thisStr = first == '0' ? "FALSE" : "TRUE";
break;
case ERROR:
thisStr = "\"ERROR:" + value.toString() + '"';
break;
case FORMULA:
// A formula could result in a string value,
// so always add double-quote characters.
thisStr = '"' + value.toString() + '"';
break;
case INLINESTR:
// TODO: have seen an example of this, so it's untested.
XSSFRichTextString rtsi = new XSSFRichTextString(
value.toString());
thisStr = rtsi.toString();
break;
case SSTINDEX:
String sstIndex = value.toString();
try {
int idx = Integer.parseInt(sstIndex);
XSSFRichTextString rtss = new XSSFRichTextString(
sharedStringsTable.getEntryAt(idx));
thisStr = rtss.toString();
} catch (NumberFormatException ex) {
// @TODO
}
break;
case NUMBER:
String n = value.toString();
BigDecimal bd = new BigDecimal(n);
// 未移除最后的0,按默认string处理
thisStr = bd.toString();
break;
case DATE:
Date date = HSSFDateUtil.getJavaDate(Double.valueOf(value.toString()));
thisStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
break;
case DATETIME:
Date dateTime = HSSFDateUtil.getJavaDate(Double.valueOf(value.toString()));
thisStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dateTime);
break;
case TIME:
Date time = HSSFDateUtil.getJavaDate(Double.valueOf(value.toString()));
thisStr = new SimpleDateFormat("HH:mm:ss").format(time);
break;
default:
thisStr = "(TODO: Unexpected type: " + nextDataType + ")";
break;
}
// 判定已解析列下标与当前下标差异,超过1则表示前面有空单元格,自动填入空串
for (int i = lastColumnNumber; i < thisColumn - 1; ++i) {
// 使用"" 作为空串
rowlist.add("");
}
rowlist.add(thisStr);
// 更新已解析列下标
if (thisColumn > -1) {
lastColumnNumber = thisColumn;
}
} else if ("row".equals(name)) {// 标识当前行结束,行数据写入结果
for (int i = lastColumnNumber; i < (this.minColumnCount); i++) {
rowlist.add("");
}
lastColumnNumber = -1;
sheetData.add(rowlist.toArray(new String[]{}));
rowlist.clear();
}
}
/**
* 添加字符
*
* @param ch char[] 添加字符串
* @param start 开始位置
* @param length 长度
* @throws SAXException SAX异常
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (vIsOpen) {
value.append(ch, start, length);
}
}
/**
* 获取当前列索引下标
*
* @param name 名字
* @return 整型
*/
private int nameToColumn(String name) {
int column = -1;
for (int i = 0; i < name.length(); ++i) {
int c = name.charAt(i);
column = (column + 1) * 26 + c - 'A';
}
return column;
}
/**
* 获取数据(单Sheet)
*
* @param sheetIndex sheet下标
* @return List<String[]>
*/
public List<String[]> getSheetData(Integer sheetIndex) {
return workData.get(sheetIndex);
}
/**
* 获取数据(多Sheet)
*
* @return Map<Integer,List<String[]>> 对应列的Map
*/
public Map<Integer, List<String[]>> getSheetData() {
return workData;
}
/**
* 取得sharedStringsTable的值
*
* @return sharedStringsTable值.
*/
public ReadOnlySharedStringsTable getSharedStringsTable() {
return sharedStringsTable;
}
/**
* 设定sharedStringsTable的值
*
* @param sharedStringsTable 设定值
*/
public void setSharedStringsTable(ReadOnlySharedStringsTable sharedStringsTable) {
this.sharedStringsTable = sharedStringsTable;
}
/**
* 取得vIsOpen的值
*
* @return vIsOpen值.
*/
public boolean isvIsOpen() {
return vIsOpen;
}
/**
* 设定vIsOpen的值
*
* @param vIsOpen 设定值
*/
public void setvIsOpen(boolean vIsOpen) {
this.vIsOpen = vIsOpen;
}
/**
* 取得nextDataType的值
*
* @return nextDataType值.
*/
public XssfDataType getNextDataType() {
return nextDataType;
}
/**
* 设定nextDataType的值
*
* @param nextDataType 设定值
*/
public void setNextDataType(XssfDataType nextDataType) {
this.nextDataType = nextDataType;
}
/**
* 取得thisColumn的值
*
* @return thisColumn值.
*/
public int getThisColumn() {
return thisColumn;
}
/**
* 设定thisColumn的值
*
* @param thisColumn 设定值
*/
public void setThisColumn(int thisColumn) {
this.thisColumn = thisColumn;
}
/**
* 取得lastColumnNumber的值
*
* @return lastColumnNumber值.
*/
public int getLastColumnNumber() {
return lastColumnNumber;
}
/**
* 设定lastColumnNumber的值
*
* @param lastColumnNumber 设定值
*/
public void setLastColumnNumber(int lastColumnNumber) {
this.lastColumnNumber = lastColumnNumber;
}
/**
* 取得value的值
*
* @return value值.
*/
public StringBuffer getValue() {
return value;
}
/**
* 设定value的值
*
* @param value 设定值
*/
public void setValue(StringBuffer value) {
this.value = value;
}
/**
* 取得rowlist的值
*
* @return rowlist值.
*/
public List<String> getRowlist() {
return rowlist;
}
/**
* 设定rowlist的值
*
* @param rowlist 设定值
*/
public void setRowlist(List<String> rowlist) {
this.rowlist = rowlist;
}
/**
* 取得sheetIndex的值
*
* @return sheetIndex值.
*/
public int getSheetIndex() {
return sheetIndex;
}
/**
* 设定sheetIndex的值
*
* @param sheetIndex 设定值
*/
public void setSheetIndex(int sheetIndex) {
this.sheetIndex = sheetIndex;
}
/**
* 取得workData的值
*
* @return workData值.
*/
public Map<Integer, List<String[]>> getWorkData() {
return workData;
}
/**
* 设定workData的值
*
* @param workData 设定值
*/
public void setWorkData(Map<Integer, List<String[]>> workData) {
this.workData = workData;
}
/**
* 取得formatter的值
*
* @return formatter值.
*/
public DataFormatter getFormatter() {
return formatter;
}
/**
* 设定formatter的值
*
* @param formatter 设定值
*/
public void setFormatter(DataFormatter formatter) {
this.formatter = formatter;
}
/**
* 取得formatIndex的值
*
* @return formatIndex值.
*/
public short getFormatIndex() {
return formatIndex;
}
/**
* 设定formatIndex的值
*
* @param formatIndex 设定值
*/
public void setFormatIndex(short formatIndex) {
this.formatIndex = formatIndex;
}
/**
* 取得formatString的值
*
* @return formatString值.
*/
public String getFormatString() {
return formatString;
}
/**
* 设定formatString的值
*
* @param formatString 设定值
*/
public void setFormatString(String formatString) {
this.formatString = formatString;
}
/**
* 取得stylesTable的值
*
* @return stylesTable值.
*/
public StylesTable getStylesTable() {
return stylesTable;
}
/**
* 设定stylesTable的值
*
* @param stylesTable 设定值
*/
public void setStylesTable(StylesTable stylesTable) {
this.stylesTable = stylesTable;
}
/**
* 取得minColumnCount的值
*
* @return minColumnCount值.
*/
public int getMinColumnCount() {
return minColumnCount;
}
/**
* 设定sheetData的值
*
* @param sheetData 设定值
*/
public void setSheetData(List<String[]> sheetData) {
this.sheetData = sheetData;
}
}
\ No newline at end of file
package com.github.wxiaoqi.security.common.util.excel;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 解析excel成html
*
* @author lipengjun
* @email 939961241@qq.com
* @date 2017年10月28日 13:11:27
*/
public class Excel2Html {
public static void main(String[] args) throws UnsupportedEncodingException {
// str = excelToHtml(realPath, "1.html");
String path = Excel2Html.class.getResource(".").getPath();
String realPath = URLDecoder.decode(path, "utf-8");
String str = excelToHtml(realPath + "\\acctExport.xlsx");
System.out.println(str);
}
public static String excelToHtml(String realPath) {
String excelFile = realPath;
//String htmlFile=realPath + "\\" + saveName + ".html";
InputStream is = null;
String content = null;
File sourcefile = null;
try {
sourcefile = new File(excelFile);
is = new FileInputStream(sourcefile);
//此WorkbookFactory在POI-3.10版本中使用需要添加dom4j
Workbook wb = WorkbookFactory.create(is);
if (wb instanceof XSSFWorkbook) {
XSSFWorkbook xWb = (XSSFWorkbook) wb;
eval = new XSSFFormulaEvaluator((XSSFWorkbook) wb);
content = getExcelInfo(xWb, true);
} else if (wb instanceof HSSFWorkbook) {
HSSFWorkbook hWb = (HSSFWorkbook) wb;
eval = new HSSFFormulaEvaluator((HSSFWorkbook) wb);
content = getExcelInfo(hWb, true);
}
//writeFile(content, htmlFile);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
if (sourcefile.exists()) {
//sourcefile.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return content;
}
private static FormulaEvaluator eval = null;
public static String getExcelInfo(Workbook wb, boolean isWithStyle) {
StringBuffer sb = new StringBuffer();
Sheet sheet = wb.getSheetAt(0);//获取第一个Sheet的内容
int lastRowNum = sheet.getLastRowNum();
Map<String, String> map[] = getRowSpanColSpanMap(sheet);
sb.append("<table style='border-collapse:collapse;' id='gv' width='100%'>");
Row row = null; //兼容
Cell cell = null; //兼容
for (int rowNum = sheet.getFirstRowNum(); rowNum <= lastRowNum; rowNum++) {
row = sheet.getRow(rowNum);
if (row == null) {
sb.append("<tr><td > </td></tr>");
continue;
}
sb.append("<tr>");
int lastColNum = row.getLastCellNum();
for (int colNum = 0; colNum < lastColNum; colNum++) {
cell = row.getCell(colNum);
if (cell == null) { //特殊情况 空白的单元格会返回null
sb.append("<td> </td>");
continue;
}
String stringValue = getCellValueFormula(cell, eval);
if (map[0].containsKey(rowNum + "," + colNum)) {
String pointString = map[0].get(rowNum + "," + colNum);
map[0].remove(rowNum + "," + colNum);
int bottomeRow = Integer.valueOf(pointString.split(",")[0]);
int bottomeCol = Integer.valueOf(pointString.split(",")[1]);
int rowSpan = bottomeRow - rowNum + 1;
int colSpan = bottomeCol - colNum + 1;
sb.append("<td rowspan= '" + rowSpan + "' colspan= '" + colSpan + "' ");
} else if (map[1].containsKey(rowNum + "," + colNum)) {
map[1].remove(rowNum + "," + colNum);
continue;
} else {
sb.append("<td ");
}
//判断是否需要样式
if (isWithStyle) {
dealExcelStyle(wb, sheet, cell, sb);//处理单元格样式
}
sb.append(">");
if (stringValue == null || "".equals(stringValue.trim())) {
sb.append(" ");
} else {
// 将ascii码为160的空格转换为html下的空格( )
sb.append(stringValue.replace(String.valueOf((char) 160), " "));
}
sb.append("</td>");
}
sb.append("</tr>");
}
sb.append("</table>");
return sb.toString();
}
private static Map<String, String>[] getRowSpanColSpanMap(Sheet sheet) {
Map<String, String> map0 = new HashMap<String, String>();
Map<String, String> map1 = new HashMap<String, String>();
int mergedNum = sheet.getNumMergedRegions();
CellRangeAddress range = null;
for (int i = 0; i < mergedNum; i++) {
range = sheet.getMergedRegion(i);
int topRow = range.getFirstRow();
int topCol = range.getFirstColumn();
int bottomRow = range.getLastRow();
int bottomCol = range.getLastColumn();
map0.put(topRow + "," + topCol, bottomRow + "," + bottomCol);
// System.out.println(topRow + "," + topCol + "," + bottomRow + "," + bottomCol);
int tempRow = topRow;
while (tempRow <= bottomRow) {
int tempCol = topCol;
while (tempCol <= bottomCol) {
map1.put(tempRow + "," + tempCol, "");
tempCol++;
}
tempRow++;
}
map1.remove(topRow + "," + topCol);
}
Map[] map = {map0, map1};
return map;
}
/**
* 获取表格单元格Cell内容
*
* @param cell
* @return
*/
private static String getCellValue(Cell cell) {
String result = new String();
switch (cell.getCellType()) {
// 数字类型
case Cell.CELL_TYPE_NUMERIC:
// 处理日期格式、时间格式
if (HSSFDateUtil.isCellDateFormatted(cell)) {
SimpleDateFormat sdf = null;
if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
sdf = new SimpleDateFormat("HH:mm");
} else {// 日期
sdf = new SimpleDateFormat("yyyy-MM-dd");
}
Date date = cell.getDateCellValue();
result = sdf.format(date);
} else if (cell.getCellStyle().getDataFormat() == 58) {
// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
double value = cell.getNumericCellValue();
Date date = org.apache.poi.ss.usermodel.DateUtil
.getJavaDate(value);
result = sdf.format(date);
} else if (cell.getCellStyle().getDataFormat() == 10) {
// 百分比格式的处理
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
DecimalFormat format = new DecimalFormat("#0.00%");
result = format.format(Double.parseDouble(value));
} else if (cell.getCellStyle().getDataFormatString().equals("0.0000%")) {
// 百分比格式的处理
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
DecimalFormat format = new DecimalFormat("#0.0000%");
result = format.format(Double.parseDouble(value));
} else {
double value = cell.getNumericCellValue();
CellStyle style = cell.getCellStyle();
DecimalFormat format = new DecimalFormat(",##0.00########");
String temp = style.getDataFormatString();
// 单元格设置成常规
if (temp.equals("General")) {
format.applyPattern("#");
}
result = format.format(value);
}
break;
// String类型
case Cell.CELL_TYPE_STRING:
result = cell.getRichStringCellValue().toString();
break;
case Cell.CELL_TYPE_BLANK:
result = "";
break;
default:
result = "";
break;
}
return result;
}
public static String getCellValueFormula(Cell cell, FormulaEvaluator formulaEvaluator) {
if (cell == null || formulaEvaluator == null) {
return null;
}
if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
DecimalFormat format = new DecimalFormat(",##0.00########");
double calcResult = formulaEvaluator.evaluate(cell).getNumberValue();
return format.format(new BigDecimal(calcResult).setScale(2, BigDecimal.ROUND_HALF_UP));
}
return getCellValue(cell);
}
/**
* 处理表格样式
*
* @param wb
* @param sheet
* @param cell
* @param sb
*/
private static void dealExcelStyle(Workbook wb, Sheet sheet, Cell cell, StringBuffer sb) {
CellStyle cellStyle = cell.getCellStyle();
if (cellStyle != null) {
short alignment = cellStyle.getAlignment();
sb.append("align='" + convertAlignToHtml(alignment) + "' ");//单元格内容的水平对齐方式
short verticalAlignment = cellStyle.getVerticalAlignment();
sb.append("valign='" + convertVerticalAlignToHtml(verticalAlignment) + "' ");//单元格中内容的垂直排列方式
if (wb instanceof XSSFWorkbook) {
XSSFFont xf = ((XSSFCellStyle) cellStyle).getFont();
short boldWeight = xf.getBoldweight();
sb.append("style='");
sb.append("font-weight:" + boldWeight + ";"); // 字体加粗
sb.append("font-size: " + xf.getFontHeight() / 2 + "%;"); // 字体大小
int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
sb.append("width:" + columnWidth + "px;");
XSSFColor xc = xf.getXSSFColor();
if (xc != null && !"".equals(xc)) {
sb.append("color:#" + xc.getARGBHex().substring(2) + ";"); // 字体颜色
}
XSSFColor bgColor = (XSSFColor) cellStyle.getFillForegroundColorColor();
if (bgColor != null && !"".equals(bgColor)) {
sb.append("background-color:#" + bgColor.getARGBHex().substring(2) + ";"); // 背景颜色
}
sb.append(getBorderStyle(0, cellStyle.getBorderTop(), ((XSSFCellStyle) cellStyle).getTopBorderXSSFColor()));
sb.append(getBorderStyle(1, cellStyle.getBorderRight(), ((XSSFCellStyle) cellStyle).getRightBorderXSSFColor()));
sb.append(getBorderStyle(2, cellStyle.getBorderBottom(), ((XSSFCellStyle) cellStyle).getBottomBorderXSSFColor()));
sb.append(getBorderStyle(3, cellStyle.getBorderLeft(), ((XSSFCellStyle) cellStyle).getLeftBorderXSSFColor()));
} else if (wb instanceof HSSFWorkbook) {
HSSFFont hf = ((HSSFCellStyle) cellStyle).getFont(wb);
short boldWeight = hf.getBoldweight();
short fontColor = hf.getColor();
sb.append("style='");
HSSFPalette palette = ((HSSFWorkbook) wb).getCustomPalette(); // 类HSSFPalette用于求的颜色的国际标准形式
HSSFColor hc = palette.getColor(fontColor);
sb.append("font-weight:" + boldWeight + ";"); // 字体加粗
sb.append("font-size: " + hf.getFontHeight() / 2 + "%;"); // 字体大小
String fontColorStr = convertToStardColor(hc);
if (fontColorStr != null && !"".equals(fontColorStr.trim())) {
sb.append("color:" + fontColorStr + ";"); // 字体颜色
}
int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
sb.append("width:" + columnWidth + "px;");
short bgColor = cellStyle.getFillForegroundColor();
hc = palette.getColor(bgColor);
String bgColorStr = convertToStardColor(hc);
if (bgColorStr != null && !"".equals(bgColorStr.trim())) {
sb.append("background-color:" + bgColorStr + ";"); // 背景颜色
}
sb.append(getBorderStyle(palette, 0, cellStyle.getBorderTop(), cellStyle.getTopBorderColor()));
sb.append(getBorderStyle(palette, 1, cellStyle.getBorderRight(), cellStyle.getRightBorderColor()));
sb.append(getBorderStyle(palette, 3, cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor()));
sb.append(getBorderStyle(palette, 2, cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor()));
}
sb.append("' ");
}
}
/**
* 单元格内容的水平对齐方式
*
* @param alignment
* @return
*/
private static String convertAlignToHtml(short alignment) {
String align = "left";
switch (alignment) {
case CellStyle.ALIGN_LEFT:
align = "left";
break;
case CellStyle.ALIGN_CENTER:
align = "center";
break;
case CellStyle.ALIGN_RIGHT:
align = "right";
break;
default:
break;
}
return align;
}
/**
* 单元格中内容的垂直排列方式
*
* @param verticalAlignment
* @return
*/
private static String convertVerticalAlignToHtml(short verticalAlignment) {
String valign = "middle";
switch (verticalAlignment) {
case CellStyle.VERTICAL_BOTTOM:
valign = "bottom";
break;
case CellStyle.VERTICAL_CENTER:
valign = "center";
break;
case CellStyle.VERTICAL_TOP:
valign = "top";
break;
default:
break;
}
return valign;
}
private static String convertToStardColor(HSSFColor hc) {
StringBuffer sb = new StringBuffer("");
if (hc != null) {
if (HSSFColor.AUTOMATIC.index == hc.getIndex()) {
return null;
}
sb.append("#");
for (int i = 0; i < hc.getTriplet().length; i++) {
sb.append(fillWithZero(Integer.toHexString(hc.getTriplet()[i])));
}
}
return sb.toString();
}
private static String fillWithZero(String str) {
if (str != null && str.length() < 2) {
return "0" + str;
}
return str;
}
static String[] bordesr = {"border-top:", "border-right:", "border-bottom:", "border-left:"};
static String[] borderStyles = {"solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid", "solid", "solid", "solid", "solid"};
private static String getBorderStyle(HSSFPalette palette, int b, short s, short t) {
if (s == 0) return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
;
String borderColorStr = convertToStardColor(palette.getColor(t));
borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000" : borderColorStr;
return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";
}
private static String getBorderStyle(int b, short s, XSSFColor xc) {
if (s == 0) return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
;
if (xc != null && !"".equals(xc)) {
String borderColorStr = xc.getARGBHex();//t.getARGBHex();
borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000" : borderColorStr.substring(2);
return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";
}
return "";
}
private static void writeFile(String content, String path) {
OutputStream os = null;
BufferedWriter bw = null;
try {
File file = new File(path);
os = new FileOutputStream(file);
bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write(content);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (os != null)
os.close();
} catch (IOException ie) {
ie.printStackTrace();
}
}
}
}
package com.github.wxiaoqi.security.common.util.excel;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;
/**
* 导出EXCEL功能包主类
* 使用POI进行EXCEL导出的功能类。
* 目前简单处理,未设置内存优化。 数据量偏大,出现性能问题时再处理。
*
* @author lipengjun
* @email 939961241@qq.com
* @date 2017年10月28日 13:11:27
*/
public class ExcelExport {
/**
* EXCEL 2003 扩展名
*/
public static final String EXCEL03_EXTENSION = ".xls";
/**
* EXCEL 2007 扩展名
*/
public static final String EXCEL07_EXTENSION = ".xlsx";
/**
* 工作表
*/
private Workbook workBook;
/**
* 导出文件名
*/
private String exportFileName;
/**
* 日志
*/
private Log logger = LogFactory.getLog(ExcelExport.class);
/**
* 默认构造方法。
* 自动生成工作表。
*/
public ExcelExport() {
this("workbook.xlsx");
}
/**
* 指定导出文件名的构造方法
* 指定导出文件名。 同时根据指定文件名的扩展名确定导出格式是03或是07 。
* 不带扩展名默认为07格式。(POI 07格式支持内存优化)
*
* @param exportFileName 要导出的文件名(带扩展名。不带扩展名默认为07)
*/
public ExcelExport(String exportFileName) {
if (StringUtils.isBlank(exportFileName)) {
exportFileName = "workbook.xlsx";
}
String fileName = exportFileName.toLowerCase();
// 根据文件名扩展名生成EXCEL格式。
if (fileName.endsWith(ExcelExport.EXCEL03_EXTENSION)) {
workBook = new HSSFWorkbook();
} else if (exportFileName.endsWith(ExcelExport.EXCEL07_EXTENSION)) {
workBook = new XSSFWorkbook();
} else {
workBook = new XSSFWorkbook();
fileName += ".xlsx";
// 按正则替换? 处理文件名最后一个字符为“.” 的问题
// fileName = fileName.replaceAll("..", ".");
}
// 最后按小写文件名输出
this.exportFileName = fileName;
}
/**
* 主要功能: 导出EXCEL到response
* 注意事项:无
*
* @param response HttpServletResponse
*/
public void export(HttpServletResponse response) {
// response.setHeader("Content-Disposition","attachment;filename=totalExcel.xls");
response.reset();
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
// response.setContentType("text/html;charset=UTF-8");
// response.setContentType("APPLICATION/*");
String fileName = null;
// 处理编码
try {
//modify by ld 2017年4月10日19:04:37 根据浏览器编码文件名
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String userAgent = request.getHeader("User-Agent");
//针对IE或者以IE为内核的浏览器:
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
fileName = URLEncoder.encode(exportFileName, "UTF-8");
} else {
//非IE浏览器的处理:
fileName = new String(exportFileName.getBytes("UTF-8"), "ISO-8859-1");
}
} catch (UnsupportedEncodingException e) {
fileName = "export.xls";
}
response.setHeader("Content-Disposition", "attachment;filename="
+ fileName);
ServletOutputStream output;
try {
output = response.getOutputStream();
workBook.write(output);
output.flush();
output.close();
} catch (IOException e) {
logger.error("导出文件出错了", e);
throw new RuntimeException("文件导出错误");
}
}
/**
* 主要功能:简单测试
* 注意事项:无
*
* @param args 参数
*/
public static void main(String[] args) {
ExcelExport ee1 = new ExcelExport();
List<Object[]> list1 = new ArrayList<Object[]>();
List<Object> obj = new ArrayList<Object>();
obj.add("370681198002042214");
obj.add(new Date());
obj.add(new Timestamp(System.currentTimeMillis()));
obj.add(1);
obj.add(11111111111111L);
obj.add(123456.123456f);
obj.add(123456789.12345678);
obj.add(new BigDecimal("123456789123456789.1234"));
obj.add(true);
list1.add(obj.toArray());
String[] header = new String[]{"身份证号", "日期", "时间", "整型", "长整", "浮点",
"双精度", "大数", "布尔"};
ee1.addSheetByArray("测试1", list1, header);
OutputStream fis;
try {
fis = new FileOutputStream("D:\\test1.xlsx");
ee1.getWorkbook().write(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 主要功能: 在EXCEL中添加一个Sheet
* 注意事项:添加Sheet 并将List<Object[]> 中的数据填充
*
* @param sheetName 表单名字
* @param list 要填充的数据 以Object[] 表示单条记录
* @param colCaption 要生成的表头
*/
public void addSheetByArray(String sheetName, List<Object[]> list,
String[] colCaption) {
// 创建表单
Sheet sheet;
if (StringUtils.isBlank(sheetName)) {
sheet = workBook.createSheet();
} else {
sheet = workBook.createSheet(sheetName);
}
// 生成标题行 (表头)
createCaptionRow(colCaption, sheet);
// 记录列数
int colNum = 0;
// 从第二行开始
int startRow = 1;
for (Object[] obj : list) {
Row row = sheet.createRow(startRow++);
int cols = createRowData(row, Arrays.asList(obj));
row.setHeight((short) 400);
colNum = colNum > cols ? colNum : cols;
}
adjustCellWidth(colNum, startRow, sheet);
}
/**
* 主要功能:在EXCEL中添加一个Sheet
* 注意事项:添加Sheet 并将List<Object[]> 中的数据填充
*
* @param sheetName 表单名字
* @param list 要填充的数据 以Map<String,Object> 表示单条记录
* @param colCaption 要生成的表头
*/
public void addSheetByMap(String sheetName, List<Map<String, Object>> list,
String[] colCaption) {
// 创建表单
Sheet sheet;
if (StringUtils.isBlank(sheetName)) {
sheet = workBook.createSheet();
} else {
sheet = workBook.createSheet(sheetName);
}
// 生成标题行 (表头)
createCaptionRow(colCaption, sheet);
int colNum = 0;
// 转换数据
// 从第二行开始
int startRow = 1;
for (Map<String, Object> map : list) {
Row row = sheet.createRow(startRow++);
int cols = createRowData(row, map.values());
row.setHeight((short) 400);
colNum = colNum > cols ? colNum : cols;
}
adjustCellWidth(colNum, startRow, sheet);
// 处理宽度
}
/**
* 主要功能: 判断fiel
* 注意事项:无
*
* @param name 要判断的字符
* @param ignores 要忽略的数组
* @return 存在返回true
*/
private boolean isInIgnors(String name, String[] ignores) {
for (String ignore : ignores) {
if (name.equals(ignore)) {
return true;
}
}
return false;
}
/**
* 主要功能: 生成每一行的数据
* 注意事项:无
*
* @param row 要处理的行
* @param coll 集合类型(List Map.values) 要处理的数据
* @return int 列数
*/
private int createRowData(Row row, Collection<Object> coll) {
int cellNum = 0;
for (Object obj : coll) {
// 空值 按照 "" 字符串处理
if (obj == null) {
obj = "";
}
// 转换一个字符串值, 以方便判断
String strValue = obj.toString();
// 创建单元格
Cell cell = row.createCell(cellNum);
// 根据单元格的类型设置值
// 公式型(普通BEAN和MAP中暂时并不存在)
if (strValue.startsWith("FORMULA:")) {
} else {
// 处理宽度
// 设置单元格的值
setCellValue(cell, obj);
}
// 处理下一个单元格
cellNum++;
}
return cellNum;
}
/**
* 主要功能: 设置某单元格的值
* 注意事项: 同时根据值类型设置样式
* TODO: 对数字类型做进一步解析和判断。 对需要按%显示的进行处理。 %可以从表头中获取?
* 对于CellType 和CellValue 的设置还需要详细参考文档,避免产生不必要的错误转换
* 日期类型格式以通用格式。 待替换为全局变量
* 数字保留小数和显示百分比格式暂时未设置
*
* @param cell 单元格
* @param obj 原始值( null已转换为"" 空字符串)
*/
private void setCellValue(Cell cell, Object obj) {
CreationHelper createHelper = workBook.getCreationHelper();
String strValue = obj.toString();
// 时间戳类型 要先判断时间戳类型再判断时期类型
if (obj instanceof Timestamp) {
// 转换为Date后赋值
Date dt = (Timestamp) obj;
// String value = DateUtil.format(dt, "yyyy-MM-dd HH:mm:ss");
CellStyle cellStyle = workBook.createCellStyle();
cellStyle.setDataFormat(createHelper.createDataFormat().getFormat(
"yyyy-MM-dd HH:mm:ss"));
cell.setCellValue(dt);
cell.setCellStyle(cellStyle);
}
// 日期型
else if (obj instanceof Date) {
// String value = DateUtil.format((Date)obj, "yyyy-MM-dd");
// cell.setCellValue(value);
CellStyle cellStyle = workBook.createCellStyle();
cellStyle.setDataFormat(createHelper.createDataFormat().getFormat(
"yyyy-MM-dd"));
cell.setCellValue((Date) obj);
cell.setCellStyle(cellStyle);
}
/*
* 由于数字类型有int、long、double、BigDecimal 多种类型 输出格式可能要求数字、百分比、保留几位小数等多种格式. 目前仅按照数字格式输出
*/
else if (obj instanceof Integer) {
cell.setCellType(CellType.NUMERIC);
DecimalFormat df = new DecimalFormat("0");
String value = df.format(obj);
cell.setCellValue(value);
} else if (obj instanceof Long) {
cell.setCellType(CellType.NUMERIC);
DecimalFormat df = new DecimalFormat("0");
String value = df.format(obj);
cell.setCellValue(value);
} else if (obj instanceof Float) {
cell.setCellType(CellType.NUMERIC);
DecimalFormat df = new DecimalFormat("0.0000");
String value = df.format(obj);
cell.setCellValue(value);
} else if (obj instanceof Double) {
cell.setCellType(CellType.NUMERIC);
DecimalFormat df = new DecimalFormat("0.0000");
String value = df.format(obj);
cell.setCellValue(value);
}
// BigDecimal
else if (obj instanceof BigDecimal) {
cell.setCellType(CellType.STRING);
cell.setCellValue(strValue);
}
// 数字 //数字型要判断 对于百分比显示 、单位是万元等的显示细节要处理
// else if (StringUtil.isFloatNumeric(strValue)) {
// cell.setCellType(CellType.NUMERIC);
// 暂时未处理BigDecimal 类型的数据,如果有问题,只能使用String
// cell.setCellValue(Double.valueOf(strValue));
// modi by zhang @2016年11月14日14:13:11 处理浮点小数格式 暂时无法统一位数
// DecimalFormat df = new DecimalFormat("0.0000");
// String whatYourWant = df.format();
// 按String 方式输出数字
// BigDecimal bd = new BigDecimal(strValue);
// cell.setCellValue(bd.toPlainString());
// 主要处理小数的位数格式,暂时不好判断,输出原值
// cell.setCellValue(strValue);
// CellStyle style = workBook.createCellStyle();
// style.setDataFormat(workBook.createDataFormat().getFormat("0.00%"));
// }
// 字符串类型
else if (obj instanceof String) {
// modi at 2016年11月14日14:27:51 by zhang
// 补充设置单元格类型,避免编码类被当作数字类型
cell.setCellType(CellType.STRING);
// end modi
cell.setCellValue(strValue);
} else {
cell.setCellType(CellType.STRING);
cell.setCellValue(strValue);
}
}
/**
* 主要功能: 生成EXCEL的第一行表头
* 注意事项: 默认按第一行生成表头。
*
* @param colCaption 表头字符数组
* @param sheet 表单
*/
private void createCaptionRow(String[] colCaption, Sheet sheet) {
// 默认第一行
Row row = sheet.createRow(0);
row.setHeight((short) 400);
if (colCaption == null) {
return;
}
// 按列生成表头
for (int i = 0; i < colCaption.length; i++) {
Cell cell = row.createCell(i);
cell.setCellStyle(getStyle("title"));
cell.setCellType(CellType.STRING);
cell.setCellValue(colCaption[i]);
}
}
/**
* 主要功能: 调整列宽
* 注意事项:无
*
* @param cols 列数
* @param rows 行数
* @param sheet sheet
*/
private void adjustCellWidth(int cols, int rows, Sheet sheet) {
int[] cellWidth = new int[cols];
// 取列中最长的行
for (int col = 0; col < cols; col++) {
for (int row = 0; row < rows; row++) {
Cell cell = sheet.getRow(row).getCell(col);
String value = getCellValue(cell);
int length = value.getBytes().length;
if (length > cellWidth[col]) {
cellWidth[col] = length;
}
}
}
for (int j = 0; j < cellWidth.length; j++) {
if (cellWidth[j] > 254) {
cellWidth[j] = 254;
}
// 设置列宽度 单位为 1/256 个字符 设置加10%
sheet.setColumnWidth(j,
cellWidth[j] * 12 > 255 ? (255 * 256 / 10) : (cellWidth[j] * 12 * 256 / 10));
}
}
/**
* 主要功能: 取单元格的值
* 注意事项:按数字和字符两种类型先处理。 BOOLEAN FORMULA 先不处理。 日期格式如何判断?
*
* @param cell 单元格
* @return 单元格的值
*/
@SuppressWarnings("deprecation")
private String getCellValue(Cell cell) {
String value = "";
try {
// 按数字和字符两种类型先处理。 BOOLEAN FORMULA 先不处理。 日期格式如何判断?
switch (cell.getCellTypeEnum()) {
case NUMERIC:
value = cell.getNumericCellValue() + "1111"; // 增加4位的长度
// 数字格式包含日期格式,但暂时无法判断日期格式
// 除非使用固定宽度。。。。。。。
break;
case STRING:
value = cell.getStringCellValue();
break;
default:
break;
}
} catch (Exception e) {
// 不对异常做处理。仅打印到控制台以供调试
// 占不打印
// e.printStackTrace();
}
return value;
}
/**
* 主要功能: 生成表头样式(默认样式)
* 注意事项:仅生成默认样式
*
* @param type 类型 title 或 data
* @return CellStyle
*/
private CellStyle getStyle(String type) {
CellStyle cs = workBook.createCellStyle();// 创建一个style
if ("title".equals(type)) {// 表头样式
Font font = workBook.createFont();// 创建一个字体
// font.setBoldweight(Font.BOLDWEIGHT_BOLD); // 粗体
font.setBold(true);
// cs.setAlignment(CellStyle.ALIGN_CENTER);// 水平居中
cs.setAlignment(HorizontalAlignment.CENTER);
cs.setFillBackgroundColor(HSSFColor.SKY_BLUE.index);// 设置背景色
cs.setFont(font);
}
return cs;
}
/**
* 取得wb的值
*
* @return wb值.
*/
public Workbook getWorkbook() {
return workBook;
}
/**
* 设定wb的值
*
* @param workBook 设定值
*/
public void setWorkbook(Workbook workBook) {
this.workBook = workBook;
}
/**
* 取得exportFileName的值
*
* @return exportFileName值.
*/
public String getExportFileName() {
return exportFileName;
}
/**
* 设定exportFileName的值
*
* @param exportFileName 设定值
*/
public void setExportFileName(String exportFileName) {
this.exportFileName = exportFileName;
}
}
package com.github.wxiaoqi.security.common.util.excel;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* Excel文件导入的基本功能类
* 可导入EXCEL2003 和 EXCEL2007格式。
*
* @author lipengjun
* @email 939961241@qq.com
* @date 2017年10月28日 13:11:27
*/
public class ExcelImport {
/**
* excel2003扩展名
*/
public static final String EXCEL03_EXTENSION = ".xls";
/**
* excel2007扩展名
*/
public static final String EXCEL07_EXTENSION = ".xlsx";
private ExcelImport() {
}
/**
* 解析EXCEL数据为 List<String[]>
*
* @param excelFile 要解析的上传EXCEL文件
* @return List<String[]) 行(列)
*/
public static List<String[]> getExcelData07(MultipartFile excelFile) {
List<String[]> resultList = null;
if (null == excelFile || excelFile.isEmpty()) {
throw new RuntimeException("文件内容为空!");
}
Excel2007Reader excel07 = new Excel2007Reader();
try {
excel07.process(excelFile.getInputStream(), false);
} catch (Exception e) {
throw new RuntimeException("excel解析失败!");
}
resultList = excel07.getSheetData(0);
return resultList;
}
/**
* 解析EXCEL数据为 List<String[]>
*
* @param excelFile 要解析的上传EXCEL文件
* @return List<String[]) 行(列)
*/
public static List<String[]> getExcelData03(MultipartFile excelFile) {
List<String[]> resultList = null;
if (null == excelFile || excelFile.isEmpty()) {
throw new RuntimeException("文件内容为空!");
}
Excel2003Reader excel03 = new Excel2003Reader();// 实例化excel处理对象
try {
excel03.process(excelFile.getInputStream());
} catch (IOException e) {
throw new RuntimeException("excel解析失败!");
}
resultList = excel03.getSheetData(0);
return resultList;
}
/**
* 通过解析MultipartFile对象获取excel内容,并且将其拼装为List<String[]>对象返回
*
* @param excelFile
* @return
* @throws Exception
*/
public static List<String[]> getExcelData(MultipartFile excelFile)
throws RuntimeException {
List<String[]> resultList = null;
if (!excelFile.isEmpty()) {// 上传的文件不能为空
String excelFileName = excelFile.getOriginalFilename();// 文件名(带后缀)
if (excelFileName.toLowerCase().endsWith(EXCEL03_EXTENSION)) {// 如果文件是以.xls为后缀
Excel2003Reader excel03 = new Excel2003Reader();// 实例化excel处理对象
try {
excel03.process(excelFile.getInputStream());
} catch (IOException e) {
throw new RuntimeException("excel解析失败!");
}
resultList = excel03.getSheetData(0);
} else if (excelFileName.toLowerCase().endsWith(EXCEL07_EXTENSION)) {// 如果文件是以.xlsx为后缀
Excel2007Reader excel07 = new Excel2007Reader();
try {
excel07.process(excelFile.getInputStream(), false);
} catch (Exception e) {
throw new RuntimeException("excel解析失败!");
}
resultList = excel07.getSheetData(0);
}
}
return resultList;
}
/**
* 通过解析MultipartFile对象获取excel内容,并且将其拼装为Map<Integer, List<String[]>>对象返回
*
* @param excelFile
* @return
* @throws Exception
*/
public static Map<Integer, List<String[]>> getExcelDataAll(MultipartFile excelFile)
throws RuntimeException {
Map<Integer, List<String[]>> result = null;
if (!excelFile.isEmpty()) {// 上传的文件不能为空
String excelFileName = excelFile.getOriginalFilename();// 文件名(带后缀)
if (excelFileName.toLowerCase().endsWith(EXCEL03_EXTENSION)) {// 如果文件是以.xls为后缀
Excel2003Reader excel03 = new Excel2003Reader();// 实例化excel处理对象
try {
excel03.process(excelFile.getInputStream());
} catch (IOException e) {
throw new RuntimeException("excel解析失败!");
}
result = excel03.getSheetData();
} else if (excelFileName.toLowerCase().endsWith(EXCEL07_EXTENSION)) {// 如果文件是以.xlsx为后缀
Excel2007Reader excel07 = new Excel2007Reader();
try {
excel07.process(excelFile.getInputStream(), true);
} catch (Exception e) {
throw new RuntimeException("excel解析失败!");
}
result = excel07.getSheetData();
}
}
return result;
}
}
package com.github.wxiaoqi.security.common.util.excel;
/**
* XSSFDataType
*
* @author lipengjun
* @email 939961241@qq.com
* @date 2017年10月28日 13:11:27
*/
public enum XssfDataType {
BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, DATE, DATETIME, TIME,
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment