正常導出excel表格使用的poi,但是導出復雜的excel有點困難,但是可以使用freemaker模板來導出復雜的excel。
-
都是先生成一個Excel表格的模板,最好是增加一行數據。具體看圖里面的步驟。
-
項目整體結構
-
下面就直接看代碼
public class Data {
//代碼復制之后直接就可以運行了
public static void main(String[] args) {
demo();
}
public static void demo() {
// 項目下的template路徑
String path = new File("").getAbsolutePath() + "\\template";
Map<String, Object> map = new HashMap<String, Object>();
// 模板所在的路徑
map.put("tempFoldPath", path);
// 生成的路徑
map.put("file", path + "/采購訂單.xls");
// 模板名稱
map.put("tampPath", "采購訂單.ftl");
// 最后生成的表格的名稱
map.put("excelName", "采購訂單-" + "Demo" + ".xls");
// 封裝數據
Map<String, Object> exlParam = new HashMap<>();
exlParam.put("findList", new Data().list());
// 調用方法,返回瀏覽器訪問的地址
String downloadUrl = ExportExcelUtil.exportExcel(map, exlParam);
}
// 自己造假數據,正常來說都是從數據庫查詢出來拼裝數據的
public List<Purbill> list() {
List<Purbill> purbillList = new ArrayList<>();
purbillList.add(new Purbill("1", "2", "名稱", "采購名稱", "規格參數", "參數指標", "場地", "10噸", 10, 20.2, 220.2, "品牌"));
return purbillList;
}
}
class Purbill {
private String bidId;
private String billno;
private String categoryName;
private String purname;
private String specparams;
private String paramnorm;
private String productAddress;
private String unit;
private Integer nums;
private Double price;
private Double totalprice;
private String brand;
public Purbill(String bidId, String billno, String categoryName, String purname, String specparams,
String paramnorm, String productAddress, String unit, Integer nums, Double price, Double totalprice,
String brand) {
super();
this.bidId = bidId;
this.billno = billno;
this.categoryName = categoryName;
this.purname = purname;
this.specparams = specparams;
this.paramnorm = paramnorm;
this.productAddress = productAddress;
this.unit = unit;
this.nums = nums;
this.price = price;
this.totalprice = totalprice;
this.brand = brand;
}
public String getBidId() {
return bidId;
}
public void setBidId(String bidId) {
this.bidId = bidId;
}
public String getBillno() {
return billno;
}
public void setBillno(String billno) {
this.billno = billno;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getPurname() {
return purname;
}
public void setPurname(String purname) {
this.purname = purname;
}
public String getSpecparams() {
return specparams;
}
public void setSpecparams(String specparams) {
this.specparams = specparams;
}
public String getParamnorm() {
return paramnorm;
}
public void setParamnorm(String paramnorm) {
this.paramnorm = paramnorm;
}
public String getProductAddress() {
return productAddress;
}
public void setProductAddress(String productAddress) {
this.productAddress = productAddress;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public Integer getNums() {
return nums;
}
public void setNums(Integer nums) {
this.nums = nums;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Double getTotalprice() {
return totalprice;
}
public void setTotalprice(Double totalprice) {
this.totalprice = totalprice;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
主要是兩個map,一個map是封裝模板的位置和生成表格的位置,第二個map是封裝的數據。正常來說導出表格之后都是返回url請求的地址,這樣在真實項目中根據地址就可以下載出來了。
- 下面是一個excel導出的一個工具類
public class ExportExcelUtil {
public static String exportExcel(Map<String, Object> map, Map<String, Object> exlParam) {
Template dateTmp = null;
Writer fw = null;
InputStream in = null;
OutputStream out = null;
try {
// 此處需要給你個版本信息,Configuration cfg = new Configuration();這個方法已經過時了
Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
String tempFoldPath = (String) map.get("tempFoldPath"); // 模板所在的路徑
String file = (String) map.get("file");// 生成表格模板的路徑
String tampPath = (String) map.get("tampPath");// 模板名稱
String excelName = (String) map.get("excelName");// 最后生成表格的名稱
// **********初始化參數**********
File tempFoldFile = new File(tempFoldPath);
if (!tempFoldFile.exists()) {
tempFoldFile.mkdirs();
}
cfg.setDirectoryForTemplateLoading(tempFoldFile);
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateUpdateDelay(0);
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// **********獲取freemaker模板**********
dateTmp = cfg.getTemplate(tampPath);
// **********將數據寫入freemaker模板**********
fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(file)), "UTF-8"));
dateTmp.process(exlParam, fw);
// **********從freemaker模板讀出數據寫到Excel表格並生成出來**********
String fileDir = "excel";
// 文件保存目錄 項目目錄下面
String filePath = new File("").getAbsolutePath();
// 生成保存文件路徑
String createPath = filePath + "/" + fileDir + "/";
// 構建源文件
File files = new File(file);
// 文件夾不存在就創建
createFolder(createPath);
// 刪除原來的文件
deleteFile(createPath + excelName);
// 構建目標文件
File fileCopy = new File(createPath + excelName);
// 目標文件不存在就創建
if (!(fileCopy.exists())) {
fileCopy.createNewFile();
}
// 源文件創建輸入流
in = new FileInputStream(files);
// 目標文件創建輸出流
out = new FileOutputStream(fileCopy, true);
// 創建字節數組
byte[] temp = new byte[1024];
int length = 0;
// 源文件讀取一部分內容
while ((length = in.read(temp)) != -1) {
// 目標文件寫入一部分內容
out.write(temp, 0, length);
}
// 資源服務器訪問目錄 這邊需要配置tomcat的虛擬路徑,就可以直接在url上面下載表格了
String serverPath = "resourceServer";
String savePath = "/" + serverPath + "/" + fileDir + "/" + excelName;
// 服務器圖片訪問目錄
return savePath;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
fw.close();
// 關閉文件輸入輸出流
in.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// 創建文件
public static boolean createFolder(String path) {
File file = new File(path);
if (!file.exists()) {
return file.mkdir();
} else {
return true;
}
}
public static boolean deleteFile(String filePath) {// 刪除單個文件
boolean flag = false;
File file = new File(filePath);
if (file.exists() && file.isFile()) {
file.delete();// 文件刪除
flag = true;
}
return true;
}
}
這個也不用多說,里面注釋基本上已經解釋清楚了,
-
因為數據放到freemaker模板里面了所以只需要使用freemaker模板的語法取出數據存放在模板里面就可以了
-
Excel導出打開出現問題的原因
當office2010之前的版本打開會出現格式不正確的提示,然后點擊確定之后還是報格式錯誤或者可以打開但是沒有數據,這種解決方法只需要將ss:ExpandedRowCount這個值設置和行數相等或者設置大一點就不會出現這種問題了。
錯誤提示
Demo地址:https://files.cnblogs.com/files/yangk1996/FreeMaker.zip