JAVA CSV導出

編寫csv導出工具類,爲了提高複用性,使用泛型和反射,傳入一個任意類型的Vo的List就可以導出.

業務要求導出訂單,訂單中有多個商品,vo中商品是一個list

剛開始使用superCsv,不知道superCsv怎麼處理這種情況,乾脆自己寫了一個.



import java.math.BigDecimal;
import java.util.Date;

import com.tunynet.groupmall.base.utils.DateUtil;
import com.tunynet.groupmall.base.utils.csvexportutil.CellList;

/**
 * @author wanrq
 * @version 0.5
 * @date Created in 2019/12/5 15:04
 * @description 導出訂單表(有快遞的訂單)
 * @modified By
 */
public class CourieredOrderVo {
    /** 接龍號 **/
	private Long id;

    /** 微信暱稱 **/
	private String weChatName;

    /** 每個商品類型的個數 **/
	private CellList goodsNumberList;

    /** 訂單金額 **/
    private BigDecimal price;

    /** 在線支付金額 **/
    private BigDecimal onlinePrice;

    /** 在線退款金額 **/
    private BigDecimal refundPrice;

    /** 用戶備註 **/
    private String userRemarks;

    /** 管理備註 **/
    private String adminRemarks;

    /** 下單時間 **/
	private Date createDate;

    /** 訂單狀態 **/
    private String status;

    /** 聯繫人 **/
    private String Contact;

    /** 聯繫電話 **/
    private String phone;

    /** 省 **/
    private String province;

    /** 市 **/
    private String city;

    /** 區(縣) **/
    private String district;

    /** 詳細地址 **/
    private String address;

    /** 物流公司 **/
    private String LogisticsCompany;

    /** 物流單號 **/
    private String LogisticsNumber;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public CellList getGoodsNumberList() {
        return goodsNumberList;
    }

    public void setGoodsNumberList(CellList goodsNumberList) {
        this.goodsNumberList = goodsNumberList;
    }

    public String getWeChatName() {
        return weChatName;
    }

    public void setWeChatName(String weChatName) {
        this.weChatName = weChatName;
    }

    public String  getCreateDate() {
        return " "+DateUtil.parseDateToStr(createDate,DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI);
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }


    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public BigDecimal getOnlinePrice() {
        return onlinePrice;
    }

    public void setOnlinePrice(BigDecimal onlinePrice) {
        this.onlinePrice = onlinePrice;
    }

    public BigDecimal getRefundPrice() {
        return refundPrice;
    }

    public void setRefundPrice(BigDecimal refundPrice) {
        this.refundPrice = refundPrice;
    }

    public String getUserRemarks() {
        return userRemarks;
    }

    public void setUserRemarks(String userRemarks) {
        this.userRemarks = userRemarks;
    }

    public String getAdminRemarks() {
        return adminRemarks;
    }

    public void setAdminRemarks(String adminRemarks) {
        this.adminRemarks = adminRemarks;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getContact() {
        return Contact;
    }

    public void setContact(String contact) {
        Contact = contact;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getDistrict() {
        return district;
    }

    public void setDistrict(String district) {
        this.district = district;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getLogisticsCompany() {
        return LogisticsCompany;
    }

    public void setLogisticsCompany(String logisticsCompany) {
        LogisticsCompany = logisticsCompany;
    }

    public String getLogisticsNumber() {
        return LogisticsNumber;
    }

    public void setLogisticsNumber(String logisticsNumber) {
        LogisticsNumber = logisticsNumber;
    }
}


import java.util.Map;

/**
 * @author wanrq
 * @version 0.5
 * @date Created in 2019/12/6 16:34
 * @description 泛型導出excel,vo裏有list,需要確定list裏有多少個元素,
 * 每個元素對應位置,這樣有null也不會顯示錯位
 * @modified By
 */
public class CellList {

    /** 每個值對應的單元格位置 **/
    private Map<Integer,Object> map;

    /** 一共有多少單元格 **/
    private Integer size;

    public CellList() {
    }

    public CellList(Integer size) {
        this.size = size;
    }

	public CellList(Map<Integer, Object> map, Integer size) {
		this.map = map;
		this.size = size;
	}

	public Map<Integer, Object> getMap() {
		return map;
	}

	public void setMap(Map<Integer, Object> map) {
		this.map = map;
	}

	public Integer getSize() {
		return size;
	}

	public void setSize(Integer size) {
		this.size = size;
	}
}


import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author wanrq
 * @version 0.5
 * @date Created in 2019/12/5 17:47
 * @description 傳入vo導出csv文件,通過getter自定義顯示效果, list爲空顯示有bug處理待加強
 * @modified By
 */
public class CsvWrite {

	private PrintWriter printWriter;

	public CsvWrite(PrintWriter printWriter) {
		this.printWriter = printWriter;
	}

	/**
	 * @author [email protected]
	 * @date Created in 2019/12/9 11:04
	 * @description csv文件編碼
	 * @version 0.5
	 * @modified By
	 * @param o 要編碼的一個單元格的數據
	 * @return String
	*/
	private String encode(Object o) {
		if (null == o) {
			return "";
		}
		String cell = o.toString();
		if("".equals(cell)){
			return "";
		}
		StringBuilder sb = new StringBuilder();
		// 避免公式
		if ('=' == cell.charAt(0)) {
			sb.append(" ");
		}
		// 有,和\n的單元格需要引號引起來
		boolean needQMarks = false;
		char[] cellChars = cell.toCharArray();
		for (char cellChar : cellChars) {
			switch (cellChar) {
			case ',':
			case '\n':
				needQMarks = true;
				sb.append(cellChar);
				break;
			case '\"':
				needQMarks = true;
				sb.append("\"\"");
				break;
			default:
				sb.append(cellChar);
				break;
			}
		}
		String encodeCell = sb.toString();
		if (needQMarks) {
			encodeCell = "\"" + encodeCell + "\"";
		}
		return encodeCell;
	}

	/**
	 * @author wanrq
	 * @date Created in 2019/12/9 11:05
	 * @description 包裝成一行csv文件數據
	 * @version 0.5
	 * @modified By
	 * @param vo 文件傳送類對象
	 * @return String
	*/
	private <T> String rowContent(T vo) {
		String[] fieldNames = Reflection.getFieldNames(vo);
		List<String> cellList = new LinkedList<>();
		for (String fieldName : fieldNames) {
			String cell = null;
			Object valueByName = null;
			try {
				// 通過getter獲取單元格數據,用戶要自定義單元格顯示可以修改vo的getter返回
				valueByName = Reflection.getFieldValueByName(fieldName, vo);
			} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
				// 部分私有變量沒有getter,獲取不到不進行任何操作
				continue;
			}
			if (valueByName instanceof CellList) {
				// 如果是單元格列表,導出多個單元格
				CellList cells = (CellList) valueByName;
				Map<Integer, Object> map = cells.getMap();
				Integer size = cells.getSize();
				for (int i = 0; i < size; i++) {
					Object o;
					if(null == map){
						o = "";
					}else{
						o=map.get(i);
					}
					cell = encode(o);
					cellList.add(cell);
				}
			} else {
				// 普通值調用toString後編碼
				cell = encode(valueByName);
				cellList.add(cell);
			}
		}
		String row = String.join(",", cellList);
		return row;
	}

	/**
	 * @author wanrq
	 * @date Created in 2019/12/9 11:07
	 * @description 寫一行
	 * @version 0.5
	 * @modified By
	 * @param vo VO
	*/
	public <T> void writeRow(T vo) {
		printWriter.println(rowContent(vo));
	}

	/**
	 * @author wanrq
	 * @date Created in 2019/12/9 11:07
	 * @description 寫多行
	 * @version 0.5
	 * @modified By
	 * @param voList VO
	 */
	public <T> void writeAll(List<T> voList) {
		for (T vo : voList) {
			writeRow(vo);
		}
	}

	/**
	 * @author wanrq
	 * @date Created in 2019/12/9 11:07
	 * @description 寫表頭
	 * @version 0.5
	 * @modified By
	 * @param titles 表頭
	 */
	public <T> void writeTitle(T[] titles) {
		List<String> encodeList = new LinkedList<>();
		for (T title : titles) {
			encodeList.add(encode(title.toString()));
		}
		String headerContent = String.join(",", encodeList);
		printWriter.println(headerContent);
	}
}

 

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