Spring Boot--POI導出excel文件下載

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);
			}
		}
	}
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章