1. 依賴
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
2. 代碼
2.1 寫入excel
/**
* 導出excel
* @param list 數據集合
* @param column 列名
* @param templatePath 模板路徑
* @param os 輸出流
*/
public static <T> void exportExcel(List<T> list, String[] column, String templatePath, OutputStream os) {
// 獲取列名map
Map<String, String> map = XmlParser.getColumnName(templatePath);
// 聲明一個工作薄
HSSFWorkbook wb = new HSSFWorkbook();
// 聲明一個單子並命名
HSSFSheet sheet = wb.createSheet("1");
// 給單子名稱一個長度
sheet.setDefaultColumnWidth((short) 15);
// 生成一個樣式
HSSFCellStyle style = wb.createCellStyle();
// 創建第一行(也可以稱爲表頭)
HSSFRow row = sheet.createRow(0);
// 樣式字體居中
style.setAlignment(HorizontalAlignment.CENTER);
// 給表頭第一行一次創建單元格
if (column == null || column.length == 0)
return ;
for (int index = 0; index < column.length; index++) {
HSSFCell cell = row.createCell((short) index);
// 名稱..
cell.setCellValue(map.get(column[index]));
cell.setCellStyle(style);
}
// 將集合轉成list
// 有可能報錯,json序列化死循環
JSONArray jsonarray = JSONArray.fromObject(list);
// 向單元格里填充數據
for (short i = 0; i < jsonarray.size(); i++) {
row = sheet.createRow(i + 1);
JSONObject jsonObject = jsonarray.getJSONObject(i);
for (int index = 0; index < column.length; index++) {
row.createCell(index).setCellValue(jsonObject.get(column[index]) + "");
}
}
try {
wb.write(os);
System.out.println("導出成功");
wb.close();
} catch (Exception e) {
e.printStackTrace();
}
}
2.2 控制層調用
/**
* 下載
*
* @throws IOException
*/
@RequestMapping("/export")
public void export(String templatePath,
HttpServletResponse response) throws IOException {
// 查詢所有的數據
List<Student> findAll = studentService.findAll();
String[] str = { "id", "name"};//列名
// 寫入文件,得到文件
Date date = new Date(System.currentTimeMillis());
// 轉換提日期輸出格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String name = dateFormat.format(date) + ".xls";
response.addHeader("Content-Disposition",
"attachment;filename=" + new String(name.getBytes("UTF-8"), "ISO8859-1"));
response.setContentType("application/octet-stream");
OutputStream toClient = null;
toClient = new BufferedOutputStream(response.getOutputStream());
ExcelUtil.exportExcel(findAll, str, templatePath, response.getOutputStream());
toClient.flush();
response.getOutputStream().close();
}
2.3 XmlParse類
/**
* Java遞歸遍歷XML中對應表中列關係
*
* @author 春風吹又生
*/
@SuppressWarnings("all")
public class XmlParser {
/**
* XML文件路徑
*/
private String XMLPath = null;
/**
* XML文檔
*/
private Document document = null;
/**
* 存儲xml元素信息的容器
*/
private List<TableInfo> tableInfoList = new ArrayList<TableInfo>();
protected Logger logger = LoggerFactory.getLogger(getClass());
public XmlParser() {
}
/**
* 初始化xml文件
*
* @param XMLPath
* 文件路徑
*/
public XmlParser(String XMLPath) {
this.XMLPath = XMLPath;
}
/**
* 打開文檔
*/
public void openXML() {
try {
SAXReader reader = new SAXReader();
this.document = reader.read(this.XMLPath);
logger.info("openXML() successful ...");
} catch (Exception e) {
logger.error("openXML() Exception:" + e.getMessage());
}
}
/**
* 打開文檔
*
* @param filePath
* 文檔路徑
* @return Document xml文件
*/
public Document openXML(String filePath) {
try {
SAXReader saxReader = new SAXReader();
this.document = saxReader.read(filePath);
logger.info("打開xml文檔:" + filePath + " 成功 ...");
return document;
} catch (Exception e) {
logger.error("打開xml文檔:" + filePath + " Exception:" + e.getMessage());
}
return null;
}
/**
* 讀取xml文件,返回List
*
* @param filePath
* 文檔路徑
* @return List 文檔的節點信息
*/
public List<TableInfo> readXml(String filePath) {
// 讀取XML文件,並得到文檔document對象
openXML(filePath);
Element root = document.getRootElement(); // 得到文檔根結點
List list = root.elements();
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Element object = (Element) iterator.next();
// 如果當前節點的名字爲tableName,則生成一個tableInfo信息
if (object.getName().equals("tableName")) {
TableInfo tinfo = new TableInfo();
// 設置表的表明,然後遍歷當前表的所有字段
tinfo.setTableName(object.attribute("name").getStringValue());
this.getElementList(object, tinfo);
tableInfoList.add(tinfo);
} else {
continue;
}
}
return this.tableInfoList;
}
/**
* 遞歸遍歷方法 <功能詳細描述>
*
* @param element
* 某一個節點開始遍歷
*/
public void getElementList(Element element, TableInfo tinfo) {
List elements = element.elements();
// 對於node結點直接操作
if ("node".equals(element.getName())) {
String ename = element.element("ename").getStringValue();
String tname = element.element("tname").getStringValue();
String typeValue = element.element("typeValue").getStringValue();
Element ref = element.element("ref");
if (ref != null) {
String refValue = ref.getText();
tinfo.getList().add(new Node(ename, tname, typeValue, refValue));
} else {
tinfo.getList().add(new Node(ename, tname, typeValue));
}
// 對當前表信息添加字段
} else {
// 當前節點不是node結點,遞歸(?)
// 代表當前節點爲tableName,遞歸其表字段
Iterator it = elements.iterator();
while (it.hasNext()) {
Element elem = (Element) it.next();
// 遞歸遍歷
getElementList(elem, tinfo);
}
}
}
/**
* 獲取節點所有屬性值 <功能詳細描述>
*
* @param element
* @return
* @see [類、類#方法、類#成員]
*/
public String getNoteAttribute(Element element) {
String xattribute = "";
DefaultAttribute e = null;
List list = element.attributes();
for (int i = 0; i < list.size(); i++) {
e = (DefaultAttribute) list.get(i);
xattribute = e.getText();
}
return xattribute;
}
/**
* 得到節點屬性
*
* @param nodeName
* @return
*/
public String getNoteAttribute(String nodeName) {
Element root = document.getRootElement();
for (Iterator iter = root.elementIterator(); iter.hasNext();) {
Element element = (Element) iter.next();
if (nodeName.equals(element.getName())) {
return getNoteAttribute(element);
}
}
return null;
}
/**
* 解析xml,得到列名
*
* @param path
* @return
*/
public static Map<String, String> getColumnName(String path) {
try {
Document document = XMLUtils.getDocument(path);
Element root = document.getRootElement(); // 得到文檔根結點
List list = root.elements();
Iterator iterator = list.iterator();
Map<String, String> columnMap = new HashMap<String, String>();
while (iterator.hasNext()) {
Element object = (Element) iterator.next();
// 如果當前節點的名字爲tableName,則生成一個tableInfo信息
if (object.getName().equals("tableName")) {
// 設置表名,然後遍歷當前表的所有字段
getElementMap(object, columnMap);
} else {
continue;
}
}
return columnMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static void getElementMap(Element element, Map<String, String> columnMap) {
List elements = element.elements();
// 對於node結點直接操作
if ("node".equals(element.getName())) {
String ename = element.element("ename").getStringValue();
String tname = element.element("tname").getStringValue();
String typeValue = element.element("typeValue").getStringValue();
Element ref = element.element("ref");
columnMap.put(tname, ename);
// 對當前表信息添加字段
} else {
// 當前節點不是node結點,遞歸(?)
// 代表當前節點爲tableName,遞歸其表字段
Iterator it = elements.iterator();
while (it.hasNext()) {
Element elem = (Element) it.next();
// 遞歸遍歷
getElementMap(elem, columnMap);
}
}
}
}