POI批量导出Excel ZIP打包下载
1.公共抽象导出Excel类
- 需要自己实现两个抽象方法:
- getColumValueForColunmName :
- 扩展方法:根据名称判断来做值得转换
- 比如:if(key==date) value='2018-11-07'
- getExcelWorkbook:
- 生成Excel方法(参数详情请参阅代码)
- getColumValueForColunmName :
package com.haixianglicai.erp.accessCount.service.base;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
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;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.haixianglicai.erp.dao.walrus.mapper.MemberQueryCountDataMapper;
import com.haixianglicai.erp.service.EnvironmentService;
import com.haixianglicai.erp.vo.MemberQueryCountDataVO;
import com.hanya.core.util.DateUtil;
import com.hanya.core.util.MD5Utils;
/**
*
* @author HX-011
*
* @param <T>
*/
public abstract class AbstractExportExcelService<T> {
protected static Logger logger = LoggerFactory.getLogger(AbstractExportExcelService.class);
//Excel保存的路径位置
public static String EXCEL_SAVE_PATH = "/excel";
//Excel 导出的最大行数
protected static int EXCEL_MAX_ROW = 65534;
@Resource(name="activityStringRedisTemplate")
protected ValueOperations<String, String> stringRedisValueOpsTemporary;
@Resource(name="activityStringRedisTemplate")
protected RedisTemplate<String, String> stringRedisTemplateTemporary;
@Autowired
protected EnvironmentService environmentService;
/**
* 生成excel工作簿
* @param titleNames:excel标题
* @param colunmNames:excel字段名
* @param dataList:数据集合
* @param colunms:需要导出excel的列明
* @return
*/
@SuppressWarnings("deprecation")
public HSSFWorkbook generateWorkbook(String titleName,String[] colunmNames, List<Map<String, Object>> dataList, String[] colunms) {
HSSFWorkbook workbook=new HSSFWorkbook();
HSSFCellStyle cellStyle = createStyle(workbook, (short) 14); //生成样式
HSSFSheet sheet=workbook.createSheet();
HSSFRow row=null;
HSSFCell cell=null;
int titleLength=colunmNames.length;
int columsLength=colunms.length;
int rowNum=0;//行数
//1.添加EXCEL标题
if(!StringUtils.isEmpty(titleName)) {
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(0,0,0,colunms.length-1));
row=sheet.createRow(rowNum);
row.setHeight((short) (25*30));
cell=row.createCell(0);
cell.setCellStyle(cellStyle);
cell.setCellValue(new HSSFRichTextString(titleName));
rowNum++;//下一行
}
//2.添加列名
cellStyle = createStyle(workbook, (short) 11);
row=sheet.createRow(rowNum);
row.setHeight((short) (25*25));
for (int i=0;i<titleLength;i++) {
sheet.setColumnWidth((short) i, (short) (55 * 100));
cell=row.createCell(i);
cell.setCellStyle(cellStyle);
cell.setCellValue(new HSSFRichTextString(colunmNames[i]));
}
rowNum++;//下一行
//3.添加数据
if(dataList!=null&&dataList.size()>0){
for(int i=0;i<dataList.size();i++){
row=sheet.createRow(rowNum);
Map<String, Object> dataMap=dataList.get(i);
for(int k=0;k<columsLength;k++){
String colunmName = colunms[k];
String columValue=dataMap.get(colunmName)==null?"":dataMap.get(colunmName).toString();
String tmpValue = getColumValueForColunmName(colunmName,columValue);
if(!StringUtils.isEmpty(tmpValue)) {
columValue=tmpValue;
}
cell=row.createCell(k);
cell.setCellValue(new HSSFRichTextString(columValue));
}
rowNum++;
}
}
return workbook;
}
/**
* 初始化样式
* @param workbook
* @param fontSize
* @return
*/
private HSSFCellStyle createStyle(HSSFWorkbook workbook,short fontSize) {
HSSFCellStyle cellStyle=workbook.createCellStyle();//样式
HSSFFont font=workbook.createFont();
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//加粗
font.setColor(HSSFColor.BLACK.index);
font.setFontHeightInPoints(fontSize);//设置字体大小
cellStyle.setFont(font);
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
return cellStyle;
}
/**
* 获取列名
* @param colunmName
* @param columValue
* @return
*/
public abstract String getColumValueForColunmName(String colunmName,String columValue);
/**
* 锁
* @param id
* @param name
* @return
*/
public boolean lock(String id,String name) {
String key = name +"-"+ id;
if(!stringRedisTemplateTemporary.hasKey(key)) {
boolean flag = stringRedisValueOpsTemporary.setIfAbsent(key, id);
stringRedisTemplateTemporary.expire(key, 1, TimeUnit.HOURS);
return flag;
}else {
return stringRedisValueOpsTemporary.setIfAbsent(key, id);
}
}
/**
* 释放锁
* @param id
* @param name
*/
public void unLock(String id,String name) {
String key = name +"-"+ id;
stringRedisTemplateTemporary.delete(key);
}
/**
* 批量导出Excel数据
* @param lists
* @param fileName
* @param path
* @param titleName
* @throws IOException
*/
public void exportExcelData(List<T> lists,String fileName,String path) throws IOException {
exportExcelData(lists, fileName, path, null);
}
/**
* 批量导出Excel数据
* @param lists:
* @param fileName
* @param path
* @param titleName
* @throws IOException
*/
public List<String> exportExcelData(List<T> lists,String fileName,String path,String titleName) throws IOException {
List<String> fileNames = new ArrayList<String>();
int size = (null == lists ? 0 : lists.size());
// 导出Excel
if (size > 0) {
logger.warn("Excel文件存储路径【"+path+"】");
if (size > EXCEL_MAX_ROW) {
int loop = size % EXCEL_MAX_ROW == 0 ? (size / EXCEL_MAX_ROW) : (size / EXCEL_MAX_ROW) + 1;
int j = 0;
for (int i = 1; i <= loop; i++) {
List<Map<String, Object>> tmpList = new ArrayList<Map<String, Object>>();
int maxRow = EXCEL_MAX_ROW * i;
if (maxRow > size) {
maxRow = size;
}
String tmpFileName = fileName+"-"+i+".xls";
logger.warn("总数:【" + size + "】--分几次导出:【" + loop + "】--循环第:【"+i+"】次--开始位置:【" + j + "】--结束位置:【" + maxRow + "】--文件名:【"+tmpFileName+"】");
for (; j < maxRow; j++) {
Map<String,Object> tmpMap = JSONObject.parseObject(JSON.toJSONString(lists.get(j)));
tmpList.add(tmpMap);
}
HSSFWorkbook workbook = getExcelWorkbook(titleName,tmpList); //获取导出workbook
exportExcel(workbook, tmpFileName, path); //输出Excel
fileNames.add(tmpFileName);
}
}else {
List<Map<String, Object>> tmpList = new ArrayList<Map<String, Object>>();
for (int i = 0; i <lists.size(); i++) {
Map<String,Object> tmpMap = JSONObject.parseObject(JSON.toJSONString(lists.get(i)));
tmpList.add(tmpMap);
}
HSSFWorkbook workbook = getExcelWorkbook(titleName,tmpList); //获取导出workbook
String tmpFileName = fileName+".xls";
logger.warn("总数:【" + size + "】--开始位置:【0】--结束位置:【" + size + "】--文件名:【"+tmpFileName+"】");
exportExcel(workbook, tmpFileName, path); //输出Excel
fileNames.add(tmpFileName);
}
}
return fileNames;
}
/**
* 获取导出Excel的工作簿
* @param data
* @return
*/
public abstract HSSFWorkbook getExcelWorkbook(String titleName,List<Map<String, Object>> data);
/**
* 导出Excel
* @param workbook
* @param fileName
* @param path
* @throws IOException
*/
public void exportExcel(HSSFWorkbook workbook, String fileName, String path) throws IOException {
OutputStream out = null;
try {
File file = new File(path);
if(!file.exists()) {
file.mkdirs();
}
//fileName = MD5Utils.MD5(fileName);
File filePath = new File(path,fileName);
out = new FileOutputStream(filePath);
workbook.write(out);
} catch (Exception e) {
logger.warn("导出excel失败: 文件名:【"+fileName+"】 文件路径:【"+path+"】");
e.printStackTrace();
throw new IOException();
} finally {
if (null != out) {
out.close();
}
}
}
/**
* 删除文件夹
* @param folderPath
*/
public static void delFolder(String folderPath) {
try {
delAllFile(folderPath); // 删除完里面所有内容
String filePath = folderPath;
filePath = filePath.toString();
java.io.File myFilePath = new java.io.File(filePath);
myFilePath.delete(); // 删除空文件夹
} catch (Exception e) {
e.printStackTrace();
logger.warn("删除文件夹失败:文件路径【"+folderPath+"】");
}
}
/**
* 删除文件
* @param path
* @return
*/
public static boolean delAllFile(String path) {
boolean flag = false;
File file = new File(path);
if (!file.exists()) {
return flag;
}
if (!file.isDirectory()) {
return flag;
}
String[] tempList = file.list();
File temp = null;
for (int i = 0; i < tempList.length; i++) {
if (path.endsWith(File.separator)) {
temp = new File(path + tempList[i]);
} else {
temp = new File(path + File.separator + tempList[i]);
}
if (temp.isFile()) {
temp.delete();
}
if (temp.isDirectory()) {
delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
delFolder(path + "/" + tempList[i]);// 再删除空文件夹
flag = true;
}
}
return flag;
}
protected String getExcelSavePath() {
return environmentService.getCompanyRealPath()+EXCEL_SAVE_PATH;
}
}
2.service 代码
package com.haixianglicai.erp.accessCount.service.impl;
import java.io.File;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.haixianglicai.erp.accessCount.service.MemberQueryCountDataService;
import com.haixianglicai.erp.accessCount.service.base.AbstractExportExcelService;
import com.hanya.core.util.DateUtil;
import com.hanya.walrus.domain.Member;
@Service
public class MemberServiceImpl extends AbstractExportExcelService<Member> {
private MemberQueryCountDataService memberQueryCountDataService;
/**
* 导出excel方法
* @param lists
* @throws Exception
*/
public void exportExcel(List<Member> lists) throws Exception {
String realPath = getExcelSavePath();
try {
long startTime = System.currentTimeMillis();
String yyyyMMdd = DateUtil.format(new Date(), DateUtil.SIMPLE_FORMAT);
realPath += File.separator + yyyyMMdd+File.separator;
String HHss = DateUtil.format(new Date(), "HHmmss");
realPath += File.separator + HHss;
String excelFileName = "excel文件名"; //需要自己定义
String excelTitleName = "excel标题名"; //需要自己定义
List<String> fileNames = exportExcelData(lists,excelFileName,realPath,excelTitleName);
long entTime = System.currentTimeMillis();
System.out.println("导出Excel【成功】:开始时间【"+startTime+"】--结束时间【"+entTime+"】");
//保存导出Excel记录
String createName = "操作人"; //需要自己定义
//此代码省略...
memberQueryCountDataService.saveExportExcelToMemberQueryCountDataTable(fileNames, realPath,excelTitleName,createName);
}catch (Exception e) {
delFolder(realPath); //删除失败的文件夹
throw new Exception();
}
}
@Override
public String getColumValueForColunmName(String colunmName, String columValue) {
String val = "";
try {
if("registRationDate".equals(colunmName)) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
val = format.format(format.parse(columValue));
}
if("capitalMoney".equals(colunmName)) {
val = covertAmount(columValue);
}
}catch (Exception e) {
e.printStackTrace();
}
return val;
}
@Override
public HSSFWorkbook getExcelWorkbook(String titleName, List<Map<String, Object>> data) {
String colunmNameStr = "phone,capitalMoney,registRationDate,typeId";
String[] colunms = colunmNameStr.split(",");
String[] colunmNames = {"手机号码","投资总金额","用户注册时间","投资计划"};
return generateWorkbook(titleName,colunmNames, data, colunms);
}
/**
* 转换成美式金额的格式 如:"123,232,434.23"
* @param str
* @return
*/
public static String covertAmount(String amount) {
if(StringUtils.isEmpty(amount)){
return "0";
}
if(Double.parseDouble(amount) == 0){
return "0";
}
DecimalFormat df = new DecimalFormat("#,###.00");
try {//避免传递的不是数字类型
return df.format(Double.valueOf(amount));
} catch (Exception e){
return "0";
}
}
}
3.控制层代码:
package com.haixianglicai.erp.accessCount.controller.base;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.haixianglicai.erp.accessCount.service.MemberQueryCountDataService;
import com.haixianglicai.erp.accessCount.service.base.AbstractExportExcelService;
import com.haixianglicai.erp.accessCount.util.CompressedFileUtil;
import com.haixianglicai.erp.service.EnvironmentService;
import com.haixianglicai.erp.support.FormResult;
import com.haixianglicai.erp.support.PageNation;
import com.haixianglicai.erp.vo.MemberQueryCountDataVO;
import com.hanya.core.util.DateUtil;
import com.hanya.core.util.MD5Utils;
/**
*
* @author HX-011
*
*/
public abstract class BaseDataQueryController {
protected static Logger logger = LoggerFactory.getLogger(BaseDataQueryController.class);
@Autowired
private EnvironmentService environmentService;
@Autowired
private MemberQueryCountDataService memberQueryCountDataService;
@RequestMapping("/{folder}/{fileName}")
public String index(@PathVariable("folder") String folder,@PathVariable("fileName") String fileName,HttpServletRequest request) {
request.setAttribute("linkUrl", link());
Enumeration<String> enumeration = request.getParameterNames();
while(enumeration.hasMoreElements()) {
String key = enumeration.nextElement();
String value = request.getParameter(key);
request.setAttribute(key, value);
}
return "/"+folder+"/"+fileName;
}
@RequestMapping("/link")
@ResponseBody
public String link() {
String link = environmentService.getRealDomain()+ AbstractExportExcelService.EXCEL_SAVE_PATH;
return link;
}
@RequestMapping("/fileSystem/list")
@ResponseBody
public PageNation<MemberQueryCountDataVO> fileSystemList(@RequestParam Map<String,Object> form) {
int total = memberQueryCountDataService.count(form);
List<MemberQueryCountDataVO> lists = memberQueryCountDataService.queryForList(form);
try {
if(total>0) {
lists = memberQueryCountDataService.queryForList(form);
}
}catch (Exception e) {
e.printStackTrace();
}
return new PageNation<MemberQueryCountDataVO>(total,lists);
}
@RequestMapping("/fileSystem/download")
public void fileSystemDownload(Long id,HttpServletResponse response) {
InputStream in = null;
ServletOutputStream out = null;
int type = -1;
String parentPath = null;
File file = null;
try {
MemberQueryCountDataVO vo = memberQueryCountDataService.findById(id);
type = vo.getType();
String filePath = vo.getFilePath();
String fileName = vo.getType()==1?vo.getName():vo.getFolderName();
parentPath = new File(filePath).getParentFile().getPath();
if(type!=1 && type!=2) {
logger.error("文件下载【type】参数类型错误!|{}|{}|{}",type,filePath,fileName);
//return new FormResult(false);
}
String _fileName = null;
if(type==1) { //打包下载
_fileName = fileName+"_"+DateUtil.format(new Date(), DateUtil.YMDHMS)+".zip";
}else { //单个下载文件名
_fileName = fileName;
}
logger.error("文件开始下载:{}|{}|{}",type,filePath,fileName);
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.addHeader("Content-Disposition", "attachment;filename="+new String(_fileName.getBytes("GBK"), "ISO-8859-1"));
out = response.getOutputStream();
if(type==1) { //下载文件夹所有文件:打包压缩文件批量下载
//压缩文件
logger.error("文件开始压缩:目录:【{}】|文件名:【{}】",filePath,_fileName);
CompressedFileUtil.compressedFile(filePath, parentPath, _fileName);
logger.error("文件开始压缩成功,保存目录:【{}】",parentPath);
file = new File(parentPath,_fileName);
}else {//单个文件下载
//String tmpFileName = MD5Utils.MD5(fileName);
file = new File(filePath,fileName);
}
//下载文件
if(file.exists()) {
in = new FileInputStream(file);
byte[] buffer = new byte[1024*4];
int len = -1;
while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
logger.error("下载文件 true"+file.getPath());
//return new FormResult(true);
}catch (Exception e) {
logger.error("下载excel文件异常!|{}",e.getMessage());
e.printStackTrace();
//return new FormResult(false);
}finally {
try {
if(null!=in) in.close();
if(null!=out) out.close();
} catch (IOException e) {
e.printStackTrace();
}
if(type==1 && null!=file && file.exists()) {
file.delete();
logger.error("删除下载zip文件:{}",file.getPath());
}
}
}
protected Map<String,Object> requestParameterToMap(HttpServletRequest request){
Map<String,Object> params = new HashMap<String,Object>();
Enumeration<String> en = request.getParameterNames();
while(en.hasMoreElements()) {
String key = en.nextElement();
String value = request.getParameter(key);
if(!StringUtils.isEmpty(key) && !StringUtils.isEmpty(value)) {
params.put(key, value);
}
}
return params;
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(DateUtil.DEFAULT_FORMAT), true));
}
}
4.工具类(Excel打包Zip):
package com.haixianglicai.erp.accessCount.util;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.springframework.util.StringUtils;
/**
* @Description: 文件压缩工具类 将指定文件/文件夹压缩成zip、rar压缩文件
*/
public class CompressedFileUtil {
public static void compressedFile(String resourcesPath, String targetPath) throws Exception {
compressedFile(resourcesPath, targetPath, null);
}
/**
* @desc 将源文件/文件夹生成指定格式的压缩文件,格式zip
* @param resourePath
* 源文件/文件夹
* @param targetPath
* 目的压缩文件保存路径
* @return void
* @throws Exception
*/
public static void compressedFile(String resourcesPath, String targetPath, String fileName) throws Exception {
File resourcesFile = new File(resourcesPath); // 源文件
File targetFile = new File(targetPath); // 目的
// 如果目的路径不存在,则新建
if (!targetFile.exists()) {
targetFile.mkdirs();
}
String targetName = (StringUtils.isEmpty(fileName) ? resourcesFile.getName() : fileName) + (fileName.indexOf(".zip")==-1?".zip":""); // 目的压缩文件名
FileOutputStream outputStream = new FileOutputStream(new File(targetPath,targetName));
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(outputStream));
createCompressedFile(out, resourcesFile, "");
out.close();
}
/**
* @desc 生成压缩文件。 如果是文件夹,则使用递归,进行文件遍历、压缩 如果是文件,直接压缩
* @param out
* 输出流
* @param file
* 目标文件
* @return void
* @throws Exception
*/
public static void createCompressedFile(ZipOutputStream out, File file, String dir) throws Exception {
//System.out.println(file.getPath());
// 如果当前的是文件夹,则进行进一步处理
if (file.isDirectory()) {
// 得到文件列表信息
File[] files = file.listFiles();
// 将文件夹添加到下一级打包目录
out.putNextEntry(new ZipEntry(dir + "/"));
dir = dir.length() == 0 ? "" : dir + "/";
// 循环将文件夹中的文件打包
for (int i = 0; i < files.length; i++) {
createCompressedFile(out, files[i], dir + files[i].getName()); // 递归处理
}
} else { // 当前的是文件,打包处理
// 文件输入流
FileInputStream fis = new FileInputStream(file);
out.putNextEntry(new ZipEntry(dir));
// 进行写操作
int j = 0;
byte[] buffer = new byte[1024];
while ((j = fis.read(buffer)) > 0) {
out.write(buffer, 0, j);
}
// 关闭输入流
fis.close();
}
}
public static void main(String[] args) {
try {
CompressedFileUtil.compressedFile("E:\\data01\\nfs\\public\\excel\\2018-10-11\\invest", "E:\\data01\\nfs\\public\\excel\\2018-10-11","2018-10-12");
// String filePath = "\\data01\\nfs\\public\\excel\\2018-10-11\\invest\\2018-10-12.zip";
// File file = new File(filePath);
// file.delete();
System.out.println("压缩文件已经生成...");
} catch (Exception e) {
System.out.println("压缩文件生成失败...");
e.printStackTrace();
}
}
}
5.创建表SQL:
CREATE TABLE `member_query_count_data` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`path` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '文件全路径',
`folder_name` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '文件夹名',
`type` int(2) DEFAULT '0' COMMENT '类型:1-文件夹 2-文件',
`status` int(2) DEFAULT '0' COMMENT '状态:1:启用 2为禁用',
`parent_id` bigint(9) DEFAULT '0' COMMENT '父类节点',
`create_date` varchar(10) COLLATE utf8_bin DEFAULT NULL COMMENT '创建日期',
`create_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT '修改人',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`name` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '导出Excel类型名称',
PRIMARY KEY (`id`),
KEY `ct` (`create_date`)
) ENGINE=InnoDB AUTO_INCREMENT=464 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='erp定向数据统计数据表';