forked from github/easyexcel
jipengfei.jpf
6 years ago
61 changed files with 1137 additions and 1283 deletions
@ -0,0 +1,30 @@ |
|||||||
|
package com.alibaba.excel.analysis; |
||||||
|
|
||||||
|
import com.alibaba.excel.event.AnalysisEventListener; |
||||||
|
import com.alibaba.excel.metadata.Sheet; |
||||||
|
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author jipengfei |
||||||
|
*/ |
||||||
|
public interface ExcelAnalyser { |
||||||
|
|
||||||
|
void init(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Object custom, AnalysisEventListener eventListener, |
||||||
|
boolean trim); |
||||||
|
|
||||||
|
void analysis(Sheet sheetParam); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void analysis(); |
||||||
|
|
||||||
|
|
||||||
|
List<Sheet> getSheets(); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,144 @@ |
|||||||
|
package com.alibaba.excel.analysis.v07; |
||||||
|
|
||||||
|
import com.alibaba.excel.analysis.BaseSaxAnalyser; |
||||||
|
import com.alibaba.excel.context.AnalysisContext; |
||||||
|
import com.alibaba.excel.exception.ExcelAnalysisException; |
||||||
|
import com.alibaba.excel.metadata.Sheet; |
||||||
|
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.xmlbeans.XmlException; |
||||||
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; |
||||||
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; |
||||||
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; |
||||||
|
import org.xml.sax.ContentHandler; |
||||||
|
import org.xml.sax.InputSource; |
||||||
|
import org.xml.sax.XMLReader; |
||||||
|
|
||||||
|
import javax.xml.parsers.SAXParser; |
||||||
|
import javax.xml.parsers.SAXParserFactory; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author jipengfei |
||||||
|
* @date 2017/08/27 |
||||||
|
*/ |
||||||
|
public class XlsxSaxAnalyser extends BaseSaxAnalyser { |
||||||
|
|
||||||
|
private XSSFReader xssfReader; |
||||||
|
|
||||||
|
private SharedStringsTable sharedStringsTable; |
||||||
|
|
||||||
|
private List<SheetSource> sheetSourceList = new ArrayList<SheetSource>(); |
||||||
|
|
||||||
|
private boolean use1904WindowDate = false; |
||||||
|
|
||||||
|
public XlsxSaxAnalyser(AnalysisContext analysisContext) throws IOException, OpenXML4JException, XmlException { |
||||||
|
this.analysisContext = analysisContext; |
||||||
|
|
||||||
|
analysisContext.setCurrentRowNum(0); |
||||||
|
this.xssfReader = new XSSFReader(OPCPackage.open(analysisContext.getInputStream())); |
||||||
|
this.sharedStringsTable = this.xssfReader.getSharedStringsTable(); |
||||||
|
|
||||||
|
InputStream workbookXml = xssfReader.getWorkbookData(); |
||||||
|
WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml); |
||||||
|
CTWorkbook wb = ctWorkbook.getWorkbook(); |
||||||
|
CTWorkbookPr prefix = wb.getWorkbookPr(); |
||||||
|
if (prefix != null) { |
||||||
|
this.use1904WindowDate = prefix.getDate1904(); |
||||||
|
} |
||||||
|
this.analysisContext.setUse1904WindowDate(use1904WindowDate); |
||||||
|
|
||||||
|
|
||||||
|
XSSFReader.SheetIterator ite; |
||||||
|
sheetSourceList = new ArrayList<SheetSource>(); |
||||||
|
ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); |
||||||
|
while (ite.hasNext()) { |
||||||
|
InputStream inputStream = ite.next(); |
||||||
|
String sheetName = ite.getSheetName(); |
||||||
|
SheetSource sheetSource = new SheetSource(sheetName, inputStream); |
||||||
|
sheetSourceList.add(sheetSource); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
protected void execute() { |
||||||
|
Sheet sheetParam = analysisContext.getCurrentSheet(); |
||||||
|
if (sheetParam != null && sheetParam.getSheetNo() > 0 && sheetSourceList.size() >= sheetParam.getSheetNo()) { |
||||||
|
InputStream sheetInputStream = sheetSourceList.get(sheetParam.getSheetNo() - 1).getInputStream(); |
||||||
|
parseXmlSource(sheetInputStream); |
||||||
|
|
||||||
|
} else { |
||||||
|
int i = 0; |
||||||
|
for (SheetSource sheetSource : sheetSourceList) { |
||||||
|
i++; |
||||||
|
analysisContext.setCurrentSheet(new Sheet(i)); |
||||||
|
parseXmlSource(sheetSource.getInputStream()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void parseXmlSource(InputStream inputStream) { |
||||||
|
InputSource sheetSource = new InputSource(inputStream); |
||||||
|
try { |
||||||
|
SAXParserFactory saxFactory = SAXParserFactory.newInstance(); |
||||||
|
saxFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); |
||||||
|
saxFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); |
||||||
|
saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); |
||||||
|
SAXParser saxParser = saxFactory.newSAXParser(); |
||||||
|
XMLReader xmlReader = saxParser.getXMLReader(); |
||||||
|
|
||||||
|
ContentHandler handler = new XlsxRowHandler(this, sharedStringsTable, analysisContext); |
||||||
|
xmlReader.setContentHandler(handler); |
||||||
|
xmlReader.parse(sheetSource); |
||||||
|
inputStream.close(); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new ExcelAnalysisException(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public List<Sheet> getSheets() { |
||||||
|
List<Sheet> sheets = new ArrayList<Sheet>(); |
||||||
|
int i = 1; |
||||||
|
for (SheetSource sheetSource : sheetSourceList) { |
||||||
|
Sheet sheet = new Sheet(i, 0); |
||||||
|
sheet.setSheetName(sheetSource.getSheetName()); |
||||||
|
i++; |
||||||
|
sheets.add(sheet); |
||||||
|
} |
||||||
|
|
||||||
|
return sheets; |
||||||
|
} |
||||||
|
|
||||||
|
class SheetSource { |
||||||
|
|
||||||
|
private String sheetName; |
||||||
|
|
||||||
|
private InputStream inputStream; |
||||||
|
|
||||||
|
public SheetSource(String sheetName, InputStream inputStream) { |
||||||
|
this.sheetName = sheetName; |
||||||
|
this.inputStream = inputStream; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSheetName() { |
||||||
|
return sheetName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSheetName(String sheetName) { |
||||||
|
this.sheetName = sheetName; |
||||||
|
} |
||||||
|
|
||||||
|
public InputStream getInputStream() { |
||||||
|
return inputStream; |
||||||
|
} |
||||||
|
|
||||||
|
public void setInputStream(InputStream inputStream) { |
||||||
|
this.inputStream = inputStream; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,8 +1,8 @@ |
|||||||
package com.alibaba.excel.util; |
package com.alibaba.excel.constant; |
||||||
|
|
||||||
/** |
/** |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
* |
* @date 2017/08/24 |
||||||
*/ |
*/ |
||||||
public class ExcelXmlConstants { |
public class ExcelXmlConstants { |
||||||
public static final String DIMENSION = "dimension"; |
public static final String DIMENSION = "dimension"; |
@ -1,140 +1,123 @@ |
|||||||
package com.alibaba.excel.read.context; |
package com.alibaba.excel.context; |
||||||
|
|
||||||
import java.io.InputStream; |
import com.alibaba.excel.event.AnalysisEventListener; |
||||||
import java.util.List; |
|
||||||
|
|
||||||
import com.alibaba.excel.read.event.AnalysisEventListener; |
|
||||||
import com.alibaba.excel.metadata.BaseRowModel; |
import com.alibaba.excel.metadata.BaseRowModel; |
||||||
import com.alibaba.excel.metadata.ExcelHeadProperty; |
import com.alibaba.excel.metadata.ExcelHeadProperty; |
||||||
import com.alibaba.excel.metadata.Sheet; |
import com.alibaba.excel.metadata.Sheet; |
||||||
import com.alibaba.excel.support.ExcelTypeEnum; |
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
/** |
/** |
||||||
* 解析文件上下文 |
|
||||||
* |
* |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
*/ |
*/ |
||||||
public interface AnalysisContext { |
public interface AnalysisContext { |
||||||
|
|
||||||
/** |
/** |
||||||
* 返回用户自定义数据 |
|
||||||
* |
* |
||||||
* @return 返回用户自定义数据 |
|
||||||
*/ |
*/ |
||||||
Object getCustom(); |
Object getCustom(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 返回当前Sheet |
|
||||||
* |
* |
||||||
* @return current read sheet |
* @return current analysis sheet |
||||||
*/ |
*/ |
||||||
Sheet getCurrentSheet(); |
Sheet getCurrentSheet(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 设置当前解析的Sheet |
|
||||||
* |
* |
||||||
* @param sheet 入参 |
* @param sheet |
||||||
*/ |
*/ |
||||||
void setCurrentSheet(Sheet sheet); |
void setCurrentSheet(Sheet sheet); |
||||||
|
|
||||||
/** |
/** |
||||||
* 返回解析的Excel类型 |
|
||||||
* |
* |
||||||
* @return excel type |
* @return excel type |
||||||
*/ |
*/ |
||||||
ExcelTypeEnum getExcelType(); |
ExcelTypeEnum getExcelType(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 返回输入IO |
|
||||||
* |
* |
||||||
* @return file io |
* @return file io |
||||||
*/ |
*/ |
||||||
InputStream getInputStream(); |
InputStream getInputStream(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 获取当前监听者 |
|
||||||
* |
* |
||||||
* @return listener |
* @return |
||||||
*/ |
*/ |
||||||
AnalysisEventListener getEventListener(); |
AnalysisEventListener getEventListener(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 获取当前行数 |
|
||||||
* |
* |
||||||
* @return 当前行 |
* @return |
||||||
*/ |
*/ |
||||||
Integer getCurrentRowNum(); |
Integer getCurrentRowNum(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 设置当前行数 |
|
||||||
* |
* |
||||||
* @param row 设置行号 |
* @param row |
||||||
*/ |
*/ |
||||||
void setCurrentRowNum(Integer row); |
void setCurrentRowNum(Integer row); |
||||||
|
|
||||||
/** |
/** |
||||||
* 返回当前sheet共有多少行数据,仅限07版excel |
|
||||||
* |
* |
||||||
* @return 总行数 |
* @return |
||||||
*/ |
*/ |
||||||
@Deprecated |
|
||||||
Integer getTotalCount(); |
Integer getTotalCount(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 设置总条数 |
|
||||||
* |
* |
||||||
* @param totalCount 总行数 |
* @param totalCount |
||||||
*/ |
*/ |
||||||
void setTotalCount(Integer totalCount); |
void setTotalCount(Integer totalCount); |
||||||
|
|
||||||
/** |
/** |
||||||
* 返回表头信息 |
|
||||||
* |
* |
||||||
* @return 表头信息 |
* @return |
||||||
*/ |
*/ |
||||||
ExcelHeadProperty getExcelHeadProperty(); |
ExcelHeadProperty getExcelHeadProperty(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 构建 ExcelHeadProperty |
|
||||||
* |
* |
||||||
* @param clazz 自定义model |
* @param clazz |
||||||
* @param headOneRow 表头内容 |
* @param headOneRow |
||||||
*/ |
*/ |
||||||
void buildExcelHeadProperty(Class<? extends BaseRowModel> clazz, List<String> headOneRow); |
void buildExcelHeadProperty(Class<? extends BaseRowModel> clazz, List<String> headOneRow); |
||||||
|
|
||||||
/** |
/** |
||||||
* 是否trim() |
|
||||||
* |
* |
||||||
* @return 是否trim |
* @return |
||||||
*/ |
*/ |
||||||
boolean trim(); |
boolean trim(); |
||||||
|
|
||||||
/** |
/** |
||||||
* |
* |
||||||
* @param result 解析结果 |
|
||||||
*/ |
*/ |
||||||
void setCurrentRowAnalysisResult(Object result); |
void setCurrentRowAnalysisResult(Object result); |
||||||
|
|
||||||
|
|
||||||
/** |
/** |
||||||
* |
* |
||||||
* @return 当前行解析结果 |
|
||||||
*/ |
*/ |
||||||
Object getCurrentRowAnalysisResult(); |
Object getCurrentRowAnalysisResult(); |
||||||
|
|
||||||
/** |
/** |
||||||
* 中断 |
* |
||||||
*/ |
*/ |
||||||
void interrupt(); |
void interrupt(); |
||||||
|
|
||||||
/** |
/** |
||||||
* |
* |
||||||
* @return 是否use1904WindowDate |
* @return |
||||||
*/ |
*/ |
||||||
boolean use1904WindowDate(); |
boolean use1904WindowDate(); |
||||||
|
|
||||||
/** |
/** |
||||||
* |
* |
||||||
* @param use1904WindowDate 是否use1904WindowDate |
* @param use1904WindowDate |
||||||
*/ |
*/ |
||||||
void setUse1904WindowDate(boolean use1904WindowDate); |
void setUse1904WindowDate(boolean use1904WindowDate); |
||||||
} |
} |
@ -1,18 +1,17 @@ |
|||||||
package com.alibaba.excel.read.context; |
package com.alibaba.excel.context; |
||||||
|
|
||||||
import java.io.InputStream; |
import com.alibaba.excel.event.AnalysisEventListener; |
||||||
import java.util.ArrayList; |
import com.alibaba.excel.exception.ExcelAnalysisException; |
||||||
import java.util.List; |
|
||||||
|
|
||||||
import com.alibaba.excel.read.event.AnalysisEventListener; |
|
||||||
import com.alibaba.excel.read.exception.ExcelAnalysisException; |
|
||||||
import com.alibaba.excel.metadata.BaseRowModel; |
import com.alibaba.excel.metadata.BaseRowModel; |
||||||
import com.alibaba.excel.metadata.ExcelHeadProperty; |
import com.alibaba.excel.metadata.ExcelHeadProperty; |
||||||
import com.alibaba.excel.metadata.Sheet; |
import com.alibaba.excel.metadata.Sheet; |
||||||
import com.alibaba.excel.support.ExcelTypeEnum; |
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
/** |
/** |
||||||
* 解析Excel上线文默认实现 |
|
||||||
* |
* |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
*/ |
*/ |
@ -0,0 +1,26 @@ |
|||||||
|
package com.alibaba.excel.event; |
||||||
|
|
||||||
|
import com.alibaba.excel.context.AnalysisContext; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* |
||||||
|
* @author jipengfei |
||||||
|
*/ |
||||||
|
public abstract class AnalysisEventListener<T> { |
||||||
|
|
||||||
|
/** |
||||||
|
* when analysis one row trigger invoke function |
||||||
|
* |
||||||
|
* @param object one row data |
||||||
|
* @param context analysis context |
||||||
|
*/ |
||||||
|
public abstract void invoke(T object, AnalysisContext context); |
||||||
|
|
||||||
|
/** |
||||||
|
* if have something to do after all analysis |
||||||
|
* |
||||||
|
* @param context |
||||||
|
*/ |
||||||
|
public abstract void doAfterAllAnalysed(AnalysisContext context); |
||||||
|
} |
@ -1,29 +1,25 @@ |
|||||||
package com.alibaba.excel.read.event; |
package com.alibaba.excel.event; |
||||||
|
|
||||||
|
|
||||||
/** |
/** |
||||||
* 管理每个监听者 |
|
||||||
* |
* |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
*/ |
*/ |
||||||
public interface AnalysisEventRegisterCenter { |
public interface AnalysisEventRegisterCenter { |
||||||
|
|
||||||
/** |
/** |
||||||
* 增加监听者 |
* @param name |
||||||
* @param name 名称 |
* @param listener |
||||||
* @param listener 监听器 |
|
||||||
*/ |
*/ |
||||||
void appendLister(String name, AnalysisEventListener listener); |
void appendLister(String name, AnalysisEventListener listener); |
||||||
|
|
||||||
|
|
||||||
/** |
/** |
||||||
* 通知所有监听者 |
* @param event |
||||||
* @param event 事件 |
|
||||||
*/ |
*/ |
||||||
void notifyListeners(OneRowAnalysisFinishEvent event); |
void notifyListeners(OneRowAnalysisFinishEvent event); |
||||||
|
|
||||||
/** |
/** |
||||||
* 清空所有监听者 |
|
||||||
*/ |
*/ |
||||||
void cleanAllListeners(); |
void cleanAllListeners(); |
||||||
} |
} |
@ -1,7 +1,8 @@ |
|||||||
package com.alibaba.excel.read.event; |
package com.alibaba.excel.event; |
||||||
|
|
||||||
/** |
/** |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
|
* @date 2017/07/21 |
||||||
*/ |
*/ |
||||||
public class OneRowAnalysisFinishEvent { |
public class OneRowAnalysisFinishEvent { |
||||||
|
|
@ -1,7 +1,6 @@ |
|||||||
package com.alibaba.excel.read.exception; |
package com.alibaba.excel.exception; |
||||||
|
|
||||||
/** |
/** |
||||||
* Excel解析时候封装的异常 |
|
||||||
* |
* |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
*/ |
*/ |
@ -1,9 +1,34 @@ |
|||||||
package com.alibaba.excel.metadata; |
package com.alibaba.excel.metadata; |
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.CellStyle; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
/** |
/** |
||||||
* Excel基础模型 |
* Excel基础模型 |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
*/ |
*/ |
||||||
public class BaseRowModel { |
public class BaseRowModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 每列样式 |
||||||
|
*/ |
||||||
|
private Map<Integer, CellStyle> cellStyleMap = new HashMap<Integer, CellStyle>(); |
||||||
|
|
||||||
|
public void addStyle(Integer row, CellStyle cellStyle){ |
||||||
|
cellStyleMap.put(row,cellStyle); |
||||||
|
} |
||||||
|
|
||||||
|
public CellStyle getStyle(Integer row){ |
||||||
|
return cellStyleMap.get(row); |
||||||
|
} |
||||||
|
|
||||||
|
public Map<Integer, CellStyle> getCellStyleMap() { |
||||||
|
return cellStyleMap; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCellStyleMap(Map<Integer, CellStyle> cellStyleMap) { |
||||||
|
this.cellStyleMap = cellStyleMap; |
||||||
|
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,58 @@ |
|||||||
|
package com.alibaba.excel.parameter; |
||||||
|
|
||||||
|
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author jipengfei |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public class AnalysisParam { |
||||||
|
|
||||||
|
/** |
||||||
|
* @see ExcelTypeEnum |
||||||
|
*/ |
||||||
|
private ExcelTypeEnum excelTypeEnum; |
||||||
|
|
||||||
|
/** |
||||||
|
* file in |
||||||
|
*/ |
||||||
|
private InputStream in; |
||||||
|
|
||||||
|
/** |
||||||
|
* user defined param to listener use |
||||||
|
*/ |
||||||
|
private Object customContent; |
||||||
|
|
||||||
|
public AnalysisParam(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent) { |
||||||
|
this.in = in; |
||||||
|
this.excelTypeEnum = excelTypeEnum; |
||||||
|
this.customContent = customContent; |
||||||
|
} |
||||||
|
|
||||||
|
public ExcelTypeEnum getExcelTypeEnum() { |
||||||
|
return excelTypeEnum; |
||||||
|
} |
||||||
|
|
||||||
|
public void setExcelTypeEnum(ExcelTypeEnum excelTypeEnum) { |
||||||
|
this.excelTypeEnum = excelTypeEnum; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getCustomContent() { |
||||||
|
return customContent; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCustomContent(Object customContent) { |
||||||
|
this.customContent = customContent; |
||||||
|
} |
||||||
|
|
||||||
|
public InputStream getIn() { |
||||||
|
return in; |
||||||
|
} |
||||||
|
|
||||||
|
public void setIn(InputStream in) { |
||||||
|
this.in = in; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.alibaba.excel.parameter; |
||||||
|
|
||||||
|
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.OutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link com.alibaba.excel.ExcelWriter} |
||||||
|
* |
||||||
|
* @author jipengfei |
||||||
|
* @date 2017/05/15 |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public class ExcelWriteParam { |
||||||
|
|
||||||
|
/** |
||||||
|
*/ |
||||||
|
private OutputStream outputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
*/ |
||||||
|
private ExcelTypeEnum type; |
||||||
|
|
||||||
|
public ExcelWriteParam(OutputStream outputStream, ExcelTypeEnum type) { |
||||||
|
this.outputStream = outputStream; |
||||||
|
this.type = type; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public OutputStream getOutputStream() { |
||||||
|
return outputStream; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOutputStream(OutputStream outputStream) { |
||||||
|
this.outputStream = outputStream; |
||||||
|
} |
||||||
|
|
||||||
|
public ExcelTypeEnum getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
public void setType(ExcelTypeEnum type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.alibaba.excel.parameter; |
||||||
|
|
||||||
|
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.OutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by jipengfei on 17/2/19. |
||||||
|
*/ |
||||||
|
public class GenerateParam { |
||||||
|
|
||||||
|
private OutputStream outputStream; |
||||||
|
|
||||||
|
private String sheetName; |
||||||
|
|
||||||
|
private Class clazz; |
||||||
|
|
||||||
|
private ExcelTypeEnum type; |
||||||
|
|
||||||
|
public GenerateParam(String sheetName, Class clazz, OutputStream outputStream) { |
||||||
|
this.outputStream = outputStream; |
||||||
|
this.sheetName = sheetName; |
||||||
|
this.clazz = clazz; |
||||||
|
} |
||||||
|
|
||||||
|
public OutputStream getOutputStream() { |
||||||
|
return outputStream; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOutputStream(OutputStream outputStream) { |
||||||
|
this.outputStream = outputStream; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public String getSheetName() { |
||||||
|
return sheetName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSheetName(String sheetName) { |
||||||
|
this.sheetName = sheetName; |
||||||
|
} |
||||||
|
|
||||||
|
public Class getClazz() { |
||||||
|
return clazz; |
||||||
|
} |
||||||
|
|
||||||
|
public void setClazz(Class clazz) { |
||||||
|
this.clazz = clazz; |
||||||
|
} |
||||||
|
|
||||||
|
public ExcelTypeEnum getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
public void setType(ExcelTypeEnum type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
} |
@ -1,54 +0,0 @@ |
|||||||
package com.alibaba.excel.read; |
|
||||||
|
|
||||||
import java.io.InputStream; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import com.alibaba.excel.read.event.AnalysisEventListener; |
|
||||||
import com.alibaba.excel.metadata.Sheet; |
|
||||||
import com.alibaba.excel.support.ExcelTypeEnum; |
|
||||||
|
|
||||||
/** |
|
||||||
* Excel解析器 |
|
||||||
* |
|
||||||
* @author jipengfei |
|
||||||
*/ |
|
||||||
public interface ExcelAnalyser { |
|
||||||
|
|
||||||
/** |
|
||||||
* Excel解析初始化 |
|
||||||
* |
|
||||||
* @param inputStream 解析为文件流 |
|
||||||
* @param excelTypeEnum 解析文件类型 |
|
||||||
* @param custom 用户自定义参数用户回调时候可以获取到 |
|
||||||
* @param eventListener 解析器需要的监听器 |
|
||||||
* @param trim 是否去空格 |
|
||||||
*/ |
|
||||||
void init(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Object custom, AnalysisEventListener eventListener, |
|
||||||
boolean trim); |
|
||||||
|
|
||||||
/** |
|
||||||
* 解析指定sheet,{@link AnalysisEventListener}监听中使用 |
|
||||||
* |
|
||||||
* @param sheetParam 入参 |
|
||||||
*/ |
|
||||||
void analysis(Sheet sheetParam); |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* 默认解析第一个sheet,解析结果在 {@link AnalysisEventListener}监听中使用 |
|
||||||
*/ |
|
||||||
void analysis(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 返回excel中包含哪些sheet |
|
||||||
* |
|
||||||
* @return 返回所有sheet |
|
||||||
*/ |
|
||||||
List<Sheet> getSheets(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 关闭流 |
|
||||||
*/ |
|
||||||
void stop(); |
|
||||||
} |
|
@ -1,331 +0,0 @@ |
|||||||
package com.alibaba.excel.read; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.FileInputStream; |
|
||||||
import java.io.FileNotFoundException; |
|
||||||
import java.io.IOException; |
|
||||||
import java.io.InputStream; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collections; |
|
||||||
import java.util.LinkedList; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Locale; |
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException; |
|
||||||
|
|
||||||
import com.alibaba.excel.read.v07.RowHandler; |
|
||||||
import com.alibaba.excel.read.v07.XmlParserFactory; |
|
||||||
import com.alibaba.excel.read.v07.XMLTempFile; |
|
||||||
import com.alibaba.excel.read.context.AnalysisContext; |
|
||||||
import com.alibaba.excel.read.exception.ExcelAnalysisException; |
|
||||||
import com.alibaba.excel.metadata.Sheet; |
|
||||||
import com.alibaba.excel.util.FileUtil; |
|
||||||
|
|
||||||
import org.apache.poi.xssf.model.SharedStringsTable; |
|
||||||
import org.apache.xmlbeans.XmlException; |
|
||||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; |
|
||||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; |
|
||||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; |
|
||||||
import org.xml.sax.Attributes; |
|
||||||
import org.xml.sax.ContentHandler; |
|
||||||
import org.xml.sax.SAXException; |
|
||||||
import org.xml.sax.helpers.DefaultHandler; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author jipengfei |
|
||||||
*/ |
|
||||||
public class SaxAnalyserV07 extends BaseSaxAnalyser { |
|
||||||
|
|
||||||
private SharedStringsTable sharedStringsTable; |
|
||||||
|
|
||||||
private List<String> sharedStringList = new LinkedList<String>(); |
|
||||||
|
|
||||||
private List<SheetSource> sheetSourceList = new ArrayList<SheetSource>(); |
|
||||||
|
|
||||||
private boolean use1904WindowDate = false; |
|
||||||
|
|
||||||
private final String path; |
|
||||||
|
|
||||||
private File tmpFile; |
|
||||||
|
|
||||||
private String workBookXMLFilePath; |
|
||||||
|
|
||||||
private String sharedStringXMLFilePath; |
|
||||||
|
|
||||||
public SaxAnalyserV07(AnalysisContext analysisContext) throws Exception { |
|
||||||
this.analysisContext = analysisContext; |
|
||||||
this.path = XMLTempFile.createPath(); |
|
||||||
this.tmpFile = new File(XMLTempFile.getTmpFilePath(path)); |
|
||||||
this.workBookXMLFilePath = XMLTempFile.getWorkBookFilePath(path); |
|
||||||
this.sharedStringXMLFilePath = XMLTempFile.getSharedStringFilePath(path); |
|
||||||
start(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void execute() { |
|
||||||
try { |
|
||||||
Sheet sheet = analysisContext.getCurrentSheet(); |
|
||||||
if (!isAnalysisAllSheets(sheet)) { |
|
||||||
if (this.sheetSourceList.size() < sheet.getSheetNo() || sheet.getSheetNo() == 0) { |
|
||||||
return; |
|
||||||
} |
|
||||||
InputStream sheetInputStream = this.sheetSourceList.get(sheet.getSheetNo() - 1).getInputStream(); |
|
||||||
parseXmlSource(sheetInputStream); |
|
||||||
return; |
|
||||||
} |
|
||||||
int i = 0; |
|
||||||
for (SheetSource sheetSource : this.sheetSourceList) { |
|
||||||
i++; |
|
||||||
this.analysisContext.setCurrentSheet(new Sheet(i)); |
|
||||||
parseXmlSource(sheetSource.getInputStream()); |
|
||||||
} |
|
||||||
|
|
||||||
} catch (Exception e) { |
|
||||||
stop(); |
|
||||||
throw new ExcelAnalysisException(e); |
|
||||||
} finally { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
private boolean isAnalysisAllSheets(Sheet sheet) { |
|
||||||
if (sheet == null) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
if (sheet.getSheetNo() < 0) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public void stop() { |
|
||||||
for (SheetSource sheet : sheetSourceList) { |
|
||||||
if (sheet.getInputStream() != null) { |
|
||||||
try { |
|
||||||
sheet.getInputStream().close(); |
|
||||||
} catch (IOException e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
FileUtil.deletefile(path); |
|
||||||
} |
|
||||||
|
|
||||||
private void parseXmlSource(InputStream inputStream) { |
|
||||||
try { |
|
||||||
ContentHandler handler = new RowHandler(this, this.sharedStringsTable, this.analysisContext, |
|
||||||
sharedStringList); |
|
||||||
XmlParserFactory.parse(inputStream, handler); |
|
||||||
inputStream.close(); |
|
||||||
} catch (Exception e) { |
|
||||||
try { |
|
||||||
inputStream.close(); |
|
||||||
} catch (IOException e1) { |
|
||||||
e1.printStackTrace(); |
|
||||||
} |
|
||||||
throw new ExcelAnalysisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public List<Sheet> getSheets() { |
|
||||||
List<Sheet> sheets = new ArrayList<Sheet>(); |
|
||||||
try { |
|
||||||
int i = 1; |
|
||||||
for (SheetSource sheetSource : this.sheetSourceList) { |
|
||||||
Sheet sheet = new Sheet(i, 0); |
|
||||||
sheet.setSheetName(sheetSource.getSheetName()); |
|
||||||
i++; |
|
||||||
sheets.add(sheet); |
|
||||||
} |
|
||||||
} catch (Exception e) { |
|
||||||
stop(); |
|
||||||
throw new ExcelAnalysisException(e); |
|
||||||
} finally { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
return sheets; |
|
||||||
} |
|
||||||
|
|
||||||
private void start() throws IOException, XmlException, ParserConfigurationException, SAXException { |
|
||||||
|
|
||||||
createTmpFile(); |
|
||||||
|
|
||||||
unZipTempFile(); |
|
||||||
|
|
||||||
initSharedStringsTable(); |
|
||||||
|
|
||||||
initUse1904WindowDate(); |
|
||||||
|
|
||||||
initSheetSourceList(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
private void createTmpFile() throws FileNotFoundException { |
|
||||||
FileUtil.writeFile(tmpFile, analysisContext.getInputStream()); |
|
||||||
} |
|
||||||
|
|
||||||
private void unZipTempFile() throws IOException { |
|
||||||
FileUtil.doUnZip(path, tmpFile); |
|
||||||
} |
|
||||||
|
|
||||||
private void initSheetSourceList() throws IOException, ParserConfigurationException, SAXException { |
|
||||||
this.sheetSourceList = new ArrayList<SheetSource>(); |
|
||||||
InputStream workbookXml = new FileInputStream(this.workBookXMLFilePath); |
|
||||||
XmlParserFactory.parse(workbookXml, new DefaultHandler() { |
|
||||||
|
|
||||||
private int id = 0; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { |
|
||||||
if (qName.toLowerCase(Locale.US).equals("sheet")) { |
|
||||||
String name = null; |
|
||||||
id++; |
|
||||||
for (int i = 0; i < attrs.getLength(); i++) { |
|
||||||
if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("name")) { |
|
||||||
name = attrs.getValue(i); |
|
||||||
} else if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("r:id")) { |
|
||||||
//id = Integer.parseInt(attrs.getValue(i).replaceAll("rId", ""));
|
|
||||||
try { |
|
||||||
InputStream inputStream = new FileInputStream(XMLTempFile.getSheetFilePath(path, id)); |
|
||||||
sheetSourceList.add(new SheetSource(id, name, inputStream)); |
|
||||||
} catch (FileNotFoundException e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
}); |
|
||||||
workbookXml.close(); |
|
||||||
Collections.sort(sheetSourceList); |
|
||||||
} |
|
||||||
|
|
||||||
private void initUse1904WindowDate() throws IOException, XmlException { |
|
||||||
InputStream workbookXml = new FileInputStream(workBookXMLFilePath); |
|
||||||
WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml); |
|
||||||
CTWorkbook wb = ctWorkbook.getWorkbook(); |
|
||||||
CTWorkbookPr prefix = wb.getWorkbookPr(); |
|
||||||
if (prefix != null) { |
|
||||||
this.use1904WindowDate = prefix.getDate1904(); |
|
||||||
} |
|
||||||
this.analysisContext.setUse1904WindowDate(use1904WindowDate); |
|
||||||
workbookXml.close(); |
|
||||||
} |
|
||||||
|
|
||||||
private void initSharedStringsTable() throws IOException, ParserConfigurationException, SAXException { |
|
||||||
|
|
||||||
InputStream inputStream = new FileInputStream(this.sharedStringXMLFilePath); |
|
||||||
//this.sharedStringsTable = new SharedStringsTable();
|
|
||||||
//this.sharedStringsTable.readFrom(inputStream);
|
|
||||||
|
|
||||||
XmlParserFactory.parse(inputStream, new DefaultHandler() { |
|
||||||
//int lastElementPosition = -1;
|
|
||||||
//
|
|
||||||
//int lastHandledElementPosition = -1;
|
|
||||||
|
|
||||||
String beforeQName = ""; |
|
||||||
|
|
||||||
String currentQName = ""; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void startElement(String uri, String localName, String qName, Attributes attributes) { |
|
||||||
//if (hasSkippedEmptySharedString()) {
|
|
||||||
// sharedStringList.add("");
|
|
||||||
//}
|
|
||||||
//if ("t".equals(qName)) {
|
|
||||||
// lastElementPosition++;
|
|
||||||
//}
|
|
||||||
if ("si".equals(qName) || "t".equals(qName)) { |
|
||||||
beforeQName = currentQName; |
|
||||||
currentQName = qName; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
//@Override
|
|
||||||
//public void endElement (String uri, String localName, String qName)
|
|
||||||
// throws SAXException
|
|
||||||
//{
|
|
||||||
// if ("si".equals(qName) || "t".equals(qName)) {
|
|
||||||
// beforeQName = qName;
|
|
||||||
// currentQName = "";
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//private boolean hasSkippedEmptySharedString() {
|
|
||||||
// return lastElementPosition > lastHandledElementPosition;
|
|
||||||
//}
|
|
||||||
|
|
||||||
@Override |
|
||||||
public void characters(char[] ch, int start, int length) { |
|
||||||
if ("t".equals(currentQName) && ("t".equals(beforeQName))) { |
|
||||||
String pre = sharedStringList.get(sharedStringList.size() - 1); |
|
||||||
String str = pre + new String(ch, start, length); |
|
||||||
sharedStringList.remove(sharedStringList.size() - 1); |
|
||||||
sharedStringList.add(str); |
|
||||||
}else if ("t".equals(currentQName) && ("si".equals(beforeQName))){ |
|
||||||
sharedStringList.add(new String(ch, start, length)); |
|
||||||
} |
|
||||||
// lastHandledElementPosition++;
|
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
}); |
|
||||||
inputStream.close(); |
|
||||||
} |
|
||||||
|
|
||||||
private class SheetSource implements Comparable<SheetSource> { |
|
||||||
|
|
||||||
private int id; |
|
||||||
|
|
||||||
private String sheetName; |
|
||||||
|
|
||||||
private InputStream inputStream; |
|
||||||
|
|
||||||
public SheetSource(int id, String sheetName, InputStream inputStream) { |
|
||||||
this.id = id; |
|
||||||
this.sheetName = sheetName; |
|
||||||
this.inputStream = inputStream; |
|
||||||
} |
|
||||||
|
|
||||||
public String getSheetName() { |
|
||||||
return sheetName; |
|
||||||
} |
|
||||||
|
|
||||||
public void setSheetName(String sheetName) { |
|
||||||
this.sheetName = sheetName; |
|
||||||
} |
|
||||||
|
|
||||||
public InputStream getInputStream() { |
|
||||||
return inputStream; |
|
||||||
} |
|
||||||
|
|
||||||
public void setInputStream(InputStream inputStream) { |
|
||||||
this.inputStream = inputStream; |
|
||||||
} |
|
||||||
|
|
||||||
public int getId() { |
|
||||||
return id; |
|
||||||
} |
|
||||||
|
|
||||||
public void setId(int id) { |
|
||||||
this.id = id; |
|
||||||
} |
|
||||||
|
|
||||||
public int compareTo(SheetSource o) { |
|
||||||
if (o.id == this.id) { |
|
||||||
return 0; |
|
||||||
} else if (o.id > this.id) { |
|
||||||
return -1; |
|
||||||
} else { |
|
||||||
return 1; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,30 +0,0 @@ |
|||||||
package com.alibaba.excel.read.event; |
|
||||||
|
|
||||||
import com.alibaba.excel.read.context.AnalysisContext; |
|
||||||
|
|
||||||
/** |
|
||||||
* 监听Excel解析每行数据 |
|
||||||
* 不能单列,每次使用new一个 |
|
||||||
* 不能单列,每次使用new一个 |
|
||||||
* 不能单列,每次使用new一个 |
|
||||||
* 重要事情说三遍 |
|
||||||
* |
|
||||||
* @author jipengfei |
|
||||||
*/ |
|
||||||
public abstract class AnalysisEventListener<T> { |
|
||||||
|
|
||||||
/** |
|
||||||
* when read one row trigger invoke function |
|
||||||
* |
|
||||||
* @param object one row data |
|
||||||
* @param context read context |
|
||||||
*/ |
|
||||||
public abstract void invoke(T object, AnalysisContext context); |
|
||||||
|
|
||||||
/** |
|
||||||
* if have something to do after all read |
|
||||||
* |
|
||||||
* @param context context |
|
||||||
*/ |
|
||||||
public abstract void doAfterAllAnalysed(AnalysisContext context); |
|
||||||
} |
|
@ -1,48 +0,0 @@ |
|||||||
package com.alibaba.excel.read.v07; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.security.SecureRandom; |
|
||||||
|
|
||||||
import com.alibaba.excel.util.EasyExcelTempFile; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author jipengfei |
|
||||||
* |
|
||||||
*/ |
|
||||||
public class XMLTempFile { |
|
||||||
|
|
||||||
private static final String TMP_FILE_NAME = "tmp.xlsx"; |
|
||||||
|
|
||||||
private static final String XL = "xl"; |
|
||||||
|
|
||||||
private static final String XML_WORKBOOK = "workbook.xml"; |
|
||||||
|
|
||||||
private static final String XML_SHARED_STRING = "sharedStrings.xml"; |
|
||||||
|
|
||||||
private static final String SHEET = "sheet"; |
|
||||||
|
|
||||||
private static final String WORK_SHEETS = "worksheets"; |
|
||||||
|
|
||||||
private static final SecureRandom random = new SecureRandom(); |
|
||||||
|
|
||||||
public static String getTmpFilePath(String path) { |
|
||||||
return path + File.separator + TMP_FILE_NAME; |
|
||||||
} |
|
||||||
|
|
||||||
public static String createPath() { |
|
||||||
return EasyExcelTempFile.getEasyExcelTmpDir() + File.separator + random.nextLong(); |
|
||||||
} |
|
||||||
|
|
||||||
public static String getWorkBookFilePath(String path) { |
|
||||||
return path + File.separator + XL + File.separator + XML_WORKBOOK; |
|
||||||
} |
|
||||||
|
|
||||||
public static String getSharedStringFilePath(String path) { |
|
||||||
return path + File.separator + XL + File.separator + XML_SHARED_STRING; |
|
||||||
} |
|
||||||
|
|
||||||
public static String getSheetFilePath(String path, int id) { |
|
||||||
return path + File.separator + XL + File.separator + WORK_SHEETS + File.separator + SHEET + id |
|
||||||
+ ".xml"; |
|
||||||
} |
|
||||||
} |
|
@ -1,42 +0,0 @@ |
|||||||
package com.alibaba.excel.read.v07; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
import java.io.InputStream; |
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException; |
|
||||||
import javax.xml.parsers.SAXParser; |
|
||||||
import javax.xml.parsers.SAXParserFactory; |
|
||||||
|
|
||||||
import org.xml.sax.ContentHandler; |
|
||||||
import org.xml.sax.InputSource; |
|
||||||
import org.xml.sax.SAXException; |
|
||||||
import org.xml.sax.XMLReader; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author jipengfei |
|
||||||
* |
|
||||||
*/ |
|
||||||
public class XmlParserFactory { |
|
||||||
|
|
||||||
/** |
|
||||||
* xml解析 |
|
||||||
* @param inputStream |
|
||||||
* @param contentHandler |
|
||||||
* @throws ParserConfigurationException |
|
||||||
* @throws SAXException |
|
||||||
* @throws IOException |
|
||||||
*/ |
|
||||||
public static void parse(InputStream inputStream, ContentHandler contentHandler) |
|
||||||
throws ParserConfigurationException, SAXException, IOException { |
|
||||||
InputSource sheetSource = new InputSource(inputStream); |
|
||||||
SAXParserFactory saxFactory = SAXParserFactory.newInstance(); |
|
||||||
//防止XML实体注注入
|
|
||||||
saxFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); |
|
||||||
saxFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); |
|
||||||
saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); |
|
||||||
SAXParser saxParser = saxFactory.newSAXParser(); |
|
||||||
XMLReader xmlReader = saxParser.getXMLReader(); |
|
||||||
xmlReader.setContentHandler(contentHandler); |
|
||||||
xmlReader.parse(sheetSource); |
|
||||||
} |
|
||||||
} |
|
@ -1,62 +0,0 @@ |
|||||||
package com.alibaba.excel.util; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
|
|
||||||
/** |
|
||||||
* 用于修复POI {@link org.apache.poi.util.DefaultTempFileCreationStrategy}在并发写,创建临时目录抛出异常的BUG。 |
|
||||||
* |
|
||||||
* @author jipengfei |
|
||||||
*/ |
|
||||||
public class EasyExcelTempFile { |
|
||||||
|
|
||||||
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; |
|
||||||
|
|
||||||
private static final String POIFILES = "poifiles"; |
|
||||||
|
|
||||||
private static final String EASY_EXCEL_FILES = "easyexcel"; |
|
||||||
|
|
||||||
/** |
|
||||||
* 在创建ExcelBuilder后尝试创建临时目录,避免poi创建时候报错 |
|
||||||
*/ |
|
||||||
public static void createPOIFilesDirectory() { |
|
||||||
|
|
||||||
String tmpDir = System.getProperty(JAVA_IO_TMPDIR); |
|
||||||
if (tmpDir == null) { |
|
||||||
throw new RuntimeException( |
|
||||||
"Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!"); |
|
||||||
} |
|
||||||
File directory = new File(tmpDir, POIFILES); |
|
||||||
if (!directory.exists()) { |
|
||||||
syncCreatePOIFilesDirectory(directory); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取环境变量的配置 |
|
||||||
* @return easyexcel临时目录 |
|
||||||
*/ |
|
||||||
public static String getEasyExcelTmpDir() { |
|
||||||
String tmpDir = System.getProperty(JAVA_IO_TMPDIR); |
|
||||||
if (tmpDir == null) { |
|
||||||
throw new RuntimeException( |
|
||||||
"Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!"); |
|
||||||
} |
|
||||||
File directory = new File(tmpDir, EASY_EXCEL_FILES); |
|
||||||
if (!directory.exists()) { |
|
||||||
syncCreatePOIFilesDirectory(directory); |
|
||||||
} |
|
||||||
return tmpDir + File.separator + EASY_EXCEL_FILES; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 如果directory 不存在则创建 |
|
||||||
* |
|
||||||
* @param directory |
|
||||||
*/ |
|
||||||
private static synchronized void syncCreatePOIFilesDirectory(File directory) { |
|
||||||
if (!directory.exists()) { |
|
||||||
directory.mkdirs(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,122 +0,0 @@ |
|||||||
package com.alibaba.excel.util; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.FileNotFoundException; |
|
||||||
import java.io.FileOutputStream; |
|
||||||
import java.io.IOException; |
|
||||||
import java.io.InputStream; |
|
||||||
import java.io.OutputStream; |
|
||||||
import java.util.Enumeration; |
|
||||||
|
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; |
|
||||||
import org.apache.commons.compress.archivers.zip.ZipFile; |
|
||||||
import org.apache.commons.compress.utils.IOUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author jipengfei |
|
||||||
*/ |
|
||||||
public class FileUtil { |
|
||||||
|
|
||||||
private static final int BUF = 4096; |
|
||||||
|
|
||||||
public static boolean writeFile(File file, InputStream stream) throws FileNotFoundException { |
|
||||||
OutputStream o = null; |
|
||||||
try { |
|
||||||
makeDirs(file.getAbsolutePath()); |
|
||||||
if (!file.exists()) { |
|
||||||
file.createNewFile(); |
|
||||||
} |
|
||||||
|
|
||||||
o = new FileOutputStream(file); |
|
||||||
byte data[] = new byte[1024]; |
|
||||||
int length = -1; |
|
||||||
while ((length = stream.read(data)) != -1) { |
|
||||||
o.write(data, 0, length); |
|
||||||
} |
|
||||||
o.flush(); |
|
||||||
return true; |
|
||||||
} catch (FileNotFoundException e) { |
|
||||||
throw new RuntimeException("FileNotFoundException occurred. ", e); |
|
||||||
} catch (IOException e) { |
|
||||||
throw new RuntimeException("IOException occurred. ", e); |
|
||||||
} finally { |
|
||||||
try { |
|
||||||
o.close(); |
|
||||||
} catch (IOException e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static boolean makeDirs(String filePath) { |
|
||||||
String folderName = getFolderName(filePath); |
|
||||||
if (folderName == null || "".equals(folderName)) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
File folder = new File(folderName); |
|
||||||
return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs(); |
|
||||||
} |
|
||||||
|
|
||||||
public static String getFolderName(String filePath) { |
|
||||||
|
|
||||||
if (filePath == null || "".equals(filePath)) { |
|
||||||
return filePath; |
|
||||||
} |
|
||||||
int filePosi = filePath.lastIndexOf(File.separator); |
|
||||||
return (filePosi == -1) ? "" : filePath.substring(0, filePosi); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 文件解压 |
|
||||||
* @param path |
|
||||||
* @param file |
|
||||||
* @return |
|
||||||
* @throws IOException |
|
||||||
*/ |
|
||||||
public static boolean doUnZip(String path, File file) throws IOException { |
|
||||||
ZipFile zipFile = new ZipFile(file, "utf-8"); |
|
||||||
Enumeration<ZipArchiveEntry> en = zipFile.getEntries(); |
|
||||||
ZipArchiveEntry ze; |
|
||||||
while (en.hasMoreElements()) { |
|
||||||
ze = en.nextElement(); |
|
||||||
if(ze.getName().contains("../")){ |
|
||||||
//防止目录穿越
|
|
||||||
throw new IllegalStateException("unsecurity zipfile!"); |
|
||||||
} |
|
||||||
File f = new File(path, ze.getName()); |
|
||||||
if (ze.isDirectory()) { |
|
||||||
f.mkdirs(); |
|
||||||
continue; |
|
||||||
} else { f.getParentFile().mkdirs(); } |
|
||||||
|
|
||||||
InputStream is = zipFile.getInputStream(ze); |
|
||||||
OutputStream os = new FileOutputStream(f); |
|
||||||
IOUtils.copy(is, os, BUF); |
|
||||||
is.close(); |
|
||||||
os.close(); |
|
||||||
} |
|
||||||
zipFile.close(); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
public static void deletefile(String delpath) { |
|
||||||
File file = new File(delpath); |
|
||||||
// 当且仅当此抽象路径名表示的文件存在且 是一个目录时,返回 true
|
|
||||||
if (!file.isDirectory()) { |
|
||||||
file.delete(); |
|
||||||
} else if (file.isDirectory()) { |
|
||||||
String[] filelist = file.list(); |
|
||||||
for (int i = 0; i < filelist.length; i++) { |
|
||||||
File delfile = new File(delpath + File.separator + filelist[i]); |
|
||||||
if (!delfile.isDirectory()) { |
|
||||||
delfile.delete(); |
|
||||||
} else if (delfile.isDirectory()) { |
|
||||||
deletefile(delpath + File.separator + filelist[i]); |
|
||||||
} |
|
||||||
} |
|
||||||
file.delete(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -1,71 +1,74 @@ |
|||||||
//package com.alibaba.excel.util;
|
package com.alibaba.excel.util; |
||||||
//
|
|
||||||
//import java.util.ArrayList;
|
import com.alibaba.excel.metadata.IndexValue; |
||||||
//import java.util.List;
|
|
||||||
//import java.util.Stack;
|
import java.util.ArrayList; |
||||||
//
|
import java.util.List; |
||||||
//import com.alibaba.excel.metadata.IndexValue;
|
import java.util.Stack; |
||||||
//
|
|
||||||
///**
|
/** |
||||||
// * 去除空Cell
|
* 去除空Cell |
||||||
// * @author jipengfei
|
* @author jipengfei |
||||||
// */
|
* @date 2017/04/13 |
||||||
//public class IndexValueConverter {
|
*/ |
||||||
// public static List<String> converter(List<IndexValue> i_list) {
|
public class IndexValueConverter { |
||||||
//
|
public static List<String> converter(List<IndexValue> i_list) { |
||||||
// List<String> tem = new ArrayList<String>();
|
|
||||||
//
|
List<String> tem = new ArrayList<String>(); |
||||||
// char[] start = {'@'};
|
|
||||||
// int j = 0;
|
char[] start = {'@'}; |
||||||
// for (; j < i_list.size(); j++) {
|
int j = 0; |
||||||
// IndexValue currentIndexValue = i_list.get(j);
|
for (; j < i_list.size(); j++) { |
||||||
// char[] currentIndex = currentIndexValue.getV_index().replaceAll("[0-9]", "").toCharArray();
|
IndexValue currentIndexValue = i_list.get(j); |
||||||
// if (j > 0) {
|
char[] currentIndex = currentIndexValue.getV_index().replaceAll("[0-9]", "").toCharArray(); |
||||||
// start = i_list.get(j - 1).getV_index().replaceAll("[0-9]", "").toCharArray();
|
if (j > 0) { |
||||||
// }
|
start = i_list.get(j - 1).getV_index().replaceAll("[0-9]", "").toCharArray(); |
||||||
// int deep = subtraction26(currentIndex, start);
|
} |
||||||
// int k = 0;
|
int deep = subtraction26(currentIndex, start); |
||||||
// for (; k < deep - 1; k++) {
|
int k = 0; |
||||||
// tem.add(null);
|
for (; k < deep - 1; k++) { |
||||||
// }
|
tem.add(null); |
||||||
// tem.add(currentIndexValue.getV_value());
|
} |
||||||
// }
|
tem.add(currentIndexValue.getV_value()); |
||||||
// return tem;
|
} |
||||||
// }
|
return tem; |
||||||
//
|
} |
||||||
// private static int subtraction26(char[] currentIndex, char[] beforeIndex) {
|
|
||||||
// int result = 0;
|
private static int subtraction26(char[] currentIndex, char[] beforeIndex) { |
||||||
//
|
int result = 0; |
||||||
// Stack<Character> currentStack = new Stack<Character>();
|
|
||||||
// Stack<Character> beforeStack = new Stack<Character>();
|
Stack<Character> currentStack = new Stack<Character>(); |
||||||
//
|
Stack<Character> berforStack = new Stack<Character>(); |
||||||
// for (int i = 0; i < currentIndex.length; i++) {
|
|
||||||
// currentStack.push(currentIndex[i]);
|
for (int i = 0; i < currentIndex.length; i++) { |
||||||
// }
|
currentStack.push(currentIndex[i]); |
||||||
// for (int i = 0; i < beforeIndex.length; i++) {
|
} |
||||||
// beforeStack.push(beforeIndex[i]);
|
for (int i = 0; i < beforeIndex.length; i++) { |
||||||
// }
|
berforStack.push(beforeIndex[i]); |
||||||
// int i = 0;
|
} |
||||||
// char beforeChar = '@';
|
int i = 0; |
||||||
// while (!currentStack.isEmpty()) {
|
char beforechar = '@'; |
||||||
// char currentChar = currentStack.pop();
|
while (!currentStack.isEmpty()) { |
||||||
// if (!beforeStack.isEmpty()) {
|
char currentChar = currentStack.pop(); |
||||||
// beforeChar = beforeStack.pop();
|
if (!berforStack.isEmpty()) { |
||||||
// }
|
beforechar = berforStack.pop(); |
||||||
// int n = currentChar - beforeChar;
|
} |
||||||
// if(n<0){
|
int n = currentChar - beforechar; |
||||||
// n = n+26;
|
if(n<0){ |
||||||
// if(!currentStack.isEmpty()){
|
n = n+26; |
||||||
// char borrow = currentStack.pop();
|
if(!currentStack.isEmpty()){ |
||||||
// char newBorrow =(char)(borrow -1);
|
char borrow = currentStack.pop(); |
||||||
// currentStack.push(newBorrow);
|
char newBorrow =(char)(borrow -1); |
||||||
// }
|
currentStack.push(newBorrow); |
||||||
// }
|
} |
||||||
// result += n * Math.pow(26, i);
|
} |
||||||
// i++;
|
|
||||||
// beforeChar='@';
|
|
||||||
// }
|
result += n * Math.pow(26, i); |
||||||
//
|
i++; |
||||||
// return result;
|
beforechar='@'; |
||||||
// }
|
} |
||||||
//}
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
||||||
|
@ -0,0 +1,41 @@ |
|||||||
|
package com.alibaba.excel.util; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author jipengfei |
||||||
|
* @date 2017/06/22 |
||||||
|
*/ |
||||||
|
public class POITempFile { |
||||||
|
|
||||||
|
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; |
||||||
|
|
||||||
|
private static final String POIFILES = "poifiles"; |
||||||
|
|
||||||
|
/** |
||||||
|
*/ |
||||||
|
public static void createPOIFilesDirectory() { |
||||||
|
|
||||||
|
String tmpDir = System.getProperty(JAVA_IO_TMPDIR); |
||||||
|
if (tmpDir == null) { |
||||||
|
throw new RuntimeException( |
||||||
|
"Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!"); |
||||||
|
} |
||||||
|
File directory = new File(tmpDir, POIFILES); |
||||||
|
if (!directory.exists()) { |
||||||
|
syncCreatePOIFilesDirectory(directory); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param directory |
||||||
|
*/ |
||||||
|
private static synchronized void syncCreatePOIFilesDirectory(File directory) { |
||||||
|
if (!directory.exists()) { |
||||||
|
directory.mkdirs(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,54 +1,31 @@ |
|||||||
package com.alibaba.excel.write; |
package com.alibaba.excel.write; |
||||||
|
|
||||||
import java.io.OutputStream; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import com.alibaba.excel.metadata.Sheet; |
import com.alibaba.excel.metadata.Sheet; |
||||||
import com.alibaba.excel.metadata.Table; |
import com.alibaba.excel.metadata.Table; |
||||||
import com.alibaba.excel.support.ExcelTypeEnum; |
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.OutputStream; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
/** |
/** |
||||||
* Excel构建器 |
|
||||||
* |
* |
||||||
* @author jipengfei |
* @author jipengfei |
||||||
*/ |
*/ |
||||||
public interface ExcelBuilder { |
public interface ExcelBuilder { |
||||||
|
|
||||||
/** |
|
||||||
* 初始化Excel构造器 |
|
||||||
* |
|
||||||
* @param out 文件输出流 |
|
||||||
* @param excelType 输出Excel类型,建议使用07版xlsx(性能,内存消耗,cpu使用都远低于03版xls) |
|
||||||
* @param needHead 是否需要将表头写入Excel |
|
||||||
*/ |
|
||||||
void init(OutputStream out, ExcelTypeEnum excelType, boolean needHead); |
|
||||||
|
|
||||||
/** |
void init(InputStream templateInputStream, OutputStream out, ExcelTypeEnum excelType, boolean needHead); |
||||||
* 向Excel增加的内容 |
|
||||||
* |
|
||||||
* @param data 数据格式 |
void addContent(List data, int startRow); |
||||||
*/ |
|
||||||
void addContent(List data); |
|
||||||
|
|
||||||
/** |
|
||||||
* 向Excel增加的内容 |
|
||||||
* |
|
||||||
* @param data 数据格式 |
|
||||||
* @param sheetParam 数据写到某个sheet中 |
|
||||||
*/ |
|
||||||
void addContent(List data, Sheet sheetParam); |
void addContent(List data, Sheet sheetParam); |
||||||
|
|
||||||
/** |
|
||||||
* 向Excel增加的内容 |
|
||||||
* |
|
||||||
* @param data 数据格式 |
|
||||||
* @param sheetParam 数据写到某个sheet中 |
|
||||||
* @param table 写到某个sheet的某个Table |
|
||||||
*/ |
|
||||||
void addContent(List data, Sheet sheetParam, Table table); |
void addContent(List data, Sheet sheetParam, Table table); |
||||||
|
|
||||||
/** |
|
||||||
* 关闭资源 |
|
||||||
*/ |
|
||||||
void finish(); |
void finish(); |
||||||
} |
} |
||||||
|
@ -0,0 +1,48 @@ |
|||||||
|
package javamodel; |
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty; |
||||||
|
import com.alibaba.excel.metadata.BaseRowModel; |
||||||
|
|
||||||
|
public class IdentificationExcel extends BaseRowModel{ |
||||||
|
@ExcelProperty(index=0) |
||||||
|
private String materialnumber; |
||||||
|
|
||||||
|
@ExcelProperty(index=17) |
||||||
|
private String unit; |
||||||
|
|
||||||
|
@ExcelProperty(index=42) |
||||||
|
private String specproc; |
||||||
|
|
||||||
|
public String getMaterialnumber() { |
||||||
|
return materialnumber; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMaterialnumber(String materialnumber) { |
||||||
|
this.materialnumber = materialnumber; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUnit() { |
||||||
|
return unit; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUnit(String unit) { |
||||||
|
this.unit = unit; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSpecproc() { |
||||||
|
return specproc; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSpecproc(String specproc) { |
||||||
|
this.specproc = specproc; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "IdentificationExcel{" + |
||||||
|
"materialnumber='" + materialnumber + '\'' + |
||||||
|
", unit='" + unit + '\'' + |
||||||
|
", specproc='" + specproc + '\'' + |
||||||
|
'}'; |
||||||
|
} |
||||||
|
} |
Binary file not shown.
Loading…
Reference in new issue