package org.springblade.common.utils;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.reflect.FieldUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Silent
 * @Description
 * @Date: Created in 10:51 2021/11/3
 * @Modified By:
 */
@Slf4j
public class ExcelWriteUtil {

	/**
	 * 写入Excel数据到流
	 *
	 * @param response   Http响应
	 * @param fileName   文件名
	 * @param excelTitle excel标题
	 * @param titleMap   标题头
	 * @param list       列表
	 */
	public static <T> void writeToResponse(final HttpServletResponse response, final String fileName, final String excelTitle, final Map<String, String> titleMap, final List<T> list, final Class<T> tClass) {
		try {
			@Cleanup ExcelWriter writer = ExcelUtil.getWriter();
			//写入标题
			writer.merge(titleMap.size() - 1, excelTitle);
			//写入标题解释
			int i = 0;
			for (T ele : list) {
				Map<String, Object> keyValueMap = new HashMap<>();
				//获取解释值
				for (Map.Entry<String, String> entry : titleMap.entrySet()) {
					try {
						//获取字段值
						Field declaredField = FieldUtils.getDeclaredField(tClass, entry.getKey(),true);
						if(ObjectUtils.isEmpty(declaredField)){
							declaredField = FieldUtils.getField(tClass, entry.getKey(),true);
						}
						//允许私有变量获取
						keyValueMap.put(entry.getValue(), declaredField.get(ele));
					} catch (Exception e) {
						keyValueMap.put(entry.getValue(), "");
						log.debug(e.getMessage());
					}
				}
				//写入数据
				if (i == 0) {
					writer.writeRow(keyValueMap, true);
				} else {
					writer.writeRow(keyValueMap, false);
				}
				i++;
			}
			//设置响应头
			response.setHeader("Content-Disposition", String.format("attachment;filename=%s%s", fileName, ".xls"));
			@Cleanup ServletOutputStream outputStream = response.getOutputStream();
			writer.flush(outputStream);
		} catch (Exception e) {
			log.error(e.getMessage());
		}
	}
}
