poi用jdom解析xml檔案方式定製Excel模板
阿新 • • 發佈:2018-12-13
java程式碼
package com.td.store.utils; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.List; import org.apache.poi.hssf.usermodel.DVConstraint; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFDataValidation; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STIconSetType; public class ExcelUtil { public static void main(String[] ager){ createTemplate("shangping.xml"); } //定製生成使用者模板資訊 /** * path 是模板資訊 XML檔案的路徑 模板資訊統一存放在專案下template資料夾下 傳檔名稱即可 * * **/ public static void createTemplate(String path){ //獲取模板配置資訊的XML檔案路徑 String realPath = System.getProperty("user.dir")+"/template/"+path; File file = new File(realPath); //用jdom解析XML模板配置檔案 SAXBuilder builder = new SAXBuilder(); try { //解析XML檔案 Document parse = builder.build(file); //建立工作薄 HSSFWorkbook wb = new HSSFWorkbook(); //建立sheet工作表 引數給工作表起個名 HSSFSheet sheet = wb.createSheet("sheet0"); //獲取XML檔案根節點 (excel節點) Element rootElement = parse.getRootElement(); //獲取模板名稱 String templateName = rootElement.getAttribute("name").getValue(); //變數行號 int rownum = 0; //變數列號 int j = 0; //獲取colgroup節點物件 Element colgroup = rootElement.getChild("colgroup"); //設定列寬 setColumnWidth(sheet,colgroup); //設定標題 //獲取標題節點 Element title = rootElement.getChild("title"); //獲取標題內的tr節點list List<Element> trs = title.getChildren("tr"); //迴圈trs節點 for (int i = 0; i < trs.size(); i++) { //獲取單個tr節點物件 Element tr = trs.get(i); //獲取tr裡面的tds物件 (也可能是個集合) List<Element> tds = tr.getChildren("td"); //建立sheet裡面的一行 HSSFRow row = sheet.createRow(rownum); //建立單元格格式 CellStyle cStyle = wb.createCellStyle(); //迴圈每一個td for (j = 0; j < tds.size(); j++) { //獲取td Element td = tds.get(j); //建立單元格物件 HSSFCell cell = row.createCell(j); //獲取td裡面的屬性物件 Attribute rowspan = td.getAttribute("rowspan"); Attribute colspan = td.getAttribute("colspan"); Attribute value = td.getAttribute("value"); //獲取value屬性的值 String val = value.getValue(); //給cell設定值 cell.setCellValue(val); //Excel單元格列計數從0開始 需要轉換下 int rspan = rowspan.getIntValue()-1; int cspan = colspan.getIntValue()-1; //設定字型 HSSFFont font = wb.createFont(); font.setFontName("仿宋_GB2312"); font.setFontHeightInPoints((short)12); cStyle.setFont(font); //合併單元格 sheet.addMergedRegion(new CellRangeAddress(rspan, rspan, 0, cspan)); } rownum++; } //設定表頭資訊 //獲取表頭物件 Element theah = rootElement.getChild("thead"); trs = theah.getChildren("tr"); for (int i = 0; i < trs.size(); i++) { Element tr = trs.get(i); HSSFRow row = sheet.createRow(rownum); List<Element> ths = tr.getChildren("th"); for (j=0; j < ths.size(); j++) { Element th = ths.get(j); Attribute valueAttr = th.getAttribute("value"); HSSFCell cell = row.createCell(j); String value = valueAttr.getValue(); cell.setCellValue(value); } rownum++; } //設定資料區域樣式 Element tbody = rootElement.getChild("tbody"); Element tr = tbody.getChild("tr"); //獲取配置檔案中,需要設定樣式的行數 int repeat = tr.getAttribute("repeat").getIntValue(); //獲取tr下面的td 每一列對應的屬性 List<Element> tds = tr.getChildren("td"); for (int i = 0; i < repeat; i++) { //建立行物件 HSSFRow row = sheet.createRow(rownum); for(j=0;j<tds.size();j++){ Element td = tds.get(j); HSSFCell cell = row.createCell(j); setType(wb,cell,td); } rownum++; } File tempFile = new File("E:\\"+templateName+".xls"); OutputStream stream = new FileOutputStream(tempFile); wb.write(stream); //關閉流 stream.close(); } catch (Exception e) { e.printStackTrace(); } } //設定單元格樣式 private static void setType(HSSFWorkbook wb, HSSFCell cell, Element td) { //獲取XML TD物件的type屬性 Attribute typeAttr = td.getAttribute("type"); //獲取type屬性值,代表資料型別 String type = typeAttr.getValue(); //單元格樣式 HSSFDataFormat format = wb.createDataFormat(); HSSFCellStyle cellStyle = wb.createCellStyle(); //判斷節點型別屬性 if("string".equals(type)){ //設定預設值 cell.setCellValue(""); cell.setCellType(CellType.STRING); }else if("double".equals(type)){ cell.setCellType(CellType.NUMERIC); }else if("int".equals(type)){ cell.setCellValue(0); cell.setCellType(CellType.NUMERIC); }else if("enum".equals(type)){ CellRangeAddressList regions = new CellRangeAddressList(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), cell.getColumnIndex()); Attribute enumAttr = td.getAttribute("format"); String enumValue = enumAttr.getValue(); DVConstraint constraint = DVConstraint.createExplicitListConstraint(enumValue.split(",")); HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint); wb.getSheetAt(0).addValidationData(dataValidation); } cell.setCellStyle(cellStyle); } //設定列寬的方法 private static void setColumnWidth(HSSFSheet sheet,Element colgroup){ List<Element> cols = colgroup.getChildren("col"); for (int i = 0; i < cols.size(); i++) { Element col = cols.get(i); Attribute width = col.getAttribute("width"); //獲取到配置的寬度,擷取計量單位 是em或者px String unit = width.getValue().replaceAll("[0-9,\\.]", ""); //獲取到配置的寬度,擷取設定值 String value = width.getValue().replaceAll(unit, ""); int v = 0; //判斷單位為空 或者為em 這裡我不用String的isEmpty判斷空是因為如果String是null,會報空指標異常,但是我不知道什麼問題,StringUtils在lang包下面沒找到,先用String的isEmpty方法 //同時計量單位為px時進入方法 if(unit.isEmpty()||"px".equals(unit)){ //poi寬度轉換為excel寬度 v = Math.round(Float.parseFloat(value)*37F); }else if("em".equals(unit)){ v = Math.round(Float.parseFloat(value)*267.5F); } //設定進去值 sheet.setColumnWidth(i, v); } } }
XML模板
<?xml version="1.0" encoding="UTF-8"?> <excel id="shangping" code="shangping" name="商品資訊模板"> <!-- 列寬資訊設定 --> <colgroup> <col index="A" width="20em"></col> <col index="B" width="20em"></col> <col index="C" width="20em"></col> <col index="D" width="20em"></col> <col index="E" width="20em"></col> <col index="F" width="20em"></col> <col index="G" width="20em"></col> </colgroup> <!-- 表頭標題資訊設定 --> <title> <tr heigth="16px"> <td rowspan="1" colspan="7" value="商品資訊匯入"></td> </tr> </title> <!-- 表頭單元格每列名稱 --> <thead> <tr height="16px"> <th value="商品名" /> <th value="市場價" /> <th value="售價" /> <th value="數量" /> <th value="分類" /> <th value="商品簡述" /> <th value="圖片路徑"></th> </tr> </thead> <!-- 每列輸入資訊指定型別 repeat屬性代表多少行需要遵循設定的樣式--> <tbody> <tr height="16px" repeat="30"> <td type="string" maxlength="40" /><!--商品名稱 --> <td type="double" /><!--市場價 --> <td type="double" /><!--售價 --> <td type="int" /><!--數量 --> <td type="enum" format="1,2,3,4,5,6,7,8,9,10" /><!--分類 --> <td type="string" maxlength="100" /><!--商品簡述 --> <td type="string" maxlength="100" /><!--圖片全名 --> </tr> </tbody> </excel>