Forráskód Böngészése

集成excel导出,契合yvanUI,需要在前端导出的时候更改名字,测试接口http://127.0.0.1:8086/user/importExcelUserOpen

peiguo 5 éve
szülő
commit
25dc3e742c

+ 4 - 0
whepi-web/src/main/java/com/bofeng/dao/UserOpenMapper.java

@@ -7,6 +7,8 @@ import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+
 
 @Mapper
 @Repository
@@ -19,4 +21,6 @@ public interface UserOpenMapper extends BaseMapper<UserOpen> {
     UserOpen selectByUserId(@Param("userId") Long userId);
 
     UserOpen selectByOpenId(@Param("openId") String openId);
+
+    List<UserOpen> getAllUser();
 }

+ 6 - 0
whepi-web/src/main/java/com/bofeng/entity/UserOpen.java

@@ -1,5 +1,6 @@
 package com.bofeng.entity;
 
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.baomidou.mybatisplus.annotations.TableField;
 import com.baomidou.mybatisplus.annotations.TableId;
 import com.baomidou.mybatisplus.annotations.TableName;
@@ -21,21 +22,26 @@ public class UserOpen {
     @TableField("be_active")
     private String beActive;
 
+    @ExcelProperty(value = "昵称", index = 0)
     @TableField("nick_name")
     private String nickName;
 
+    @ExcelProperty(value = "性别", index = 1)
     @TableField("sex_desc")
     private String sexDesc;
 
     @TableField("sex")
     private Integer sex;
 
+    @ExcelProperty(value = "城市", index = 2)
     @TableField("city")
     private String city;
 
+    @ExcelProperty(value = "省", index = 3)
     @TableField("province")
     private String province;
 
+    @ExcelProperty(value = "国家", index = 4)
     @TableField("country")
     private String country;
 

+ 146 - 0
whepi-web/src/main/java/com/bofeng/excel/ExcelBuilder.java

@@ -0,0 +1,146 @@
+package com.bofeng.excel;
+
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.metadata.ExcelColumnProperty;
+import com.alibaba.excel.metadata.Sheet;
+import com.alibaba.excel.metadata.Table;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.util.StringUtils;
+import com.alibaba.excel.util.TypeUtil;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import lombok.*;
+import net.sf.cglib.beans.BeanMap;
+import org.joda.time.DateTime;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Getter
+@Setter
+public class ExcelBuilder {
+
+    private List<List<?>> sheetList = Lists.newArrayList();
+    private List<Class> sheetClazzList = Lists.newArrayList();
+    private List<String> sheetNameList = Lists.newArrayList();
+
+    public <T> ExcelBuilder writeSheet(Class<T> clazz, List<T> data, String sheetName) {
+        sheetList.add(data);
+        sheetClazzList.add(clazz);
+        sheetNameList.add(sheetName);
+        return this;
+    }
+
+    public <T> ExcelBuilder writeSheet(Class<T> clazz, List<T> data) {
+        return writeSheet(clazz, data, "");
+    }
+
+    @SneakyThrows
+    public void export(HttpServletResponse response) {
+        response.setContentType("application/vnd.ms-excel;charset=utf-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + new String(("file.xlsx").getBytes(), "iso-8859-1"));
+        try (OutputStream outputStream = response.getOutputStream()) {
+
+            ExcelWriter writer = new ExcelWriter(outputStream, ExcelTypeEnum.XLSX);
+
+            var z = 0;
+            for (val dataBean : sheetList) {
+                //建立Sheet
+                Sheet sheet = new Sheet(z + 1, 0);
+                if (!Strings.isNullOrEmpty(sheetNameList.get(z))) {
+                    sheet.setSheetName(sheetNameList.get(z));
+                } else {
+                    sheet.setSheetName("Sheet" + (z + 1));
+                }
+
+                //获取表头注解
+                ExcelHeadProperty2 head = new ExcelHeadProperty2<>(sheetClazzList.get(z));
+
+                //获取数据
+                List<List<String>> data = new ArrayList<>();
+                for (Object d : dataBean) {
+                    BeanMap beanMap = BeanMap.create(d);
+
+                    List<String> item = new ArrayList<>();
+                    for (Object obj : head.getColumnPropertyList()) {
+                        ExcelColumnProperty excelHeadProperty = (ExcelColumnProperty) obj;
+                        String cellValue = getFieldStringValue(beanMap, excelHeadProperty.getField().getName(),
+                                excelHeadProperty.getFormat());
+                        item.add(cellValue);
+                    }
+                    data.add(item);
+                }
+
+                //构造表头
+                List<List<String>> h = Lists.newArrayList();
+                int size = 0;
+                int trows = head.getRowNum();
+                for (int i = 0; i < trows; i++) {
+                    h.add(head.getHeadByRowNum(i));
+                    if (i == 0) {
+                        size = head.getHeadByRowNum(i).size();
+                    }
+                }
+                List<List<String>> v = Lists.newArrayList();
+                for (int i = 0; i < size; i++) {
+                    v.add(new ArrayList<>(trows));
+                }
+                for (int i = 0; i < size; i++) {
+                    for (int j = 0; j < trows; j++) {
+                        v.get(i).add(h.get(j).get(i));
+                    }
+                }
+
+                Table table = new Table(z);
+                table.setHead(v);
+
+                //以数组方式生成数据
+                writer.write0(data, sheet, table);
+                z++;
+            }
+
+            writer.finish();
+        }
+    }
+
+    // 导出excel如果遇到 Date 格式自动格式化年月日,DateTime 格式自动格式化年月日时分秒
+    public static String getFieldStringValue(BeanMap beanMap, String fieldName, String format) {
+        String cellValue = null;
+        Object value = beanMap.get(fieldName);
+        if (value != null) {
+            if (value instanceof Date) {
+                cellValue = formatDate((Date)value, format);
+            } else if (value instanceof DateTime) {
+                cellValue = formatDate((DateTime)value, format);
+            } else {
+                cellValue = value.toString();
+            }
+        }
+        return cellValue;
+    }
+
+    public static String formatDate(Date cellValue, String format) {
+        SimpleDateFormat simpleDateFormat;
+        if(!StringUtils.isEmpty(format)) {
+            simpleDateFormat = new SimpleDateFormat(format);
+        }else {
+            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        }
+        return simpleDateFormat.format(cellValue);
+    }
+
+    public static String formatDate(DateTime cellValue, String format) {
+        SimpleDateFormat simpleDateFormat;
+        Date date = new Date(cellValue.getMillis());
+        if(!StringUtils.isEmpty(format)) {
+            simpleDateFormat = new SimpleDateFormat(format);
+        }else {
+            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        }
+        return simpleDateFormat.format(date);
+    }
+}

+ 286 - 0
whepi-web/src/main/java/com/bofeng/excel/ExcelDataReader.java

@@ -0,0 +1,286 @@
+package com.bofeng.excel;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.excel.metadata.ExcelColumnProperty;
+import com.alibaba.excel.util.TypeUtil;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.yvan.platform.JsonWapper;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import net.sf.cglib.beans.BeanMap;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@Slf4j
+public class ExcelDataReader<T> extends AnalysisEventListener<List<String>> {
+
+    public static final String ATTRIB_NAME = "ExcelDataReader";
+    private static final int ERROR_ROWS_LIMIT = 100;
+
+    private final AtomicInteger cursor = new AtomicInteger(-1);
+    private final List<RowInfo<T>> data = Lists.newArrayList();
+    private ExcelHeadProperty2<T> headProperty;
+    private final int limitRows;
+    private boolean limitExecuted = false;
+    public String FILE_NAME = "";
+
+    private final AtomicInteger errorCount = new AtomicInteger(0);
+
+    /**
+     * 全局错误(不是在行、不是在值上的错误)
+     */
+    private final List<String> globalError = Lists.newArrayList();
+
+    /**
+     * 业务数据
+     */
+    private Object bizData;
+
+    /**
+     * 业务导入行数
+     */
+    private AtomicInteger successRows = new AtomicInteger(0);
+
+    public ExcelDataReader(Class<T> clazz, int limitRows) {
+        headProperty = new ExcelHeadProperty2<>(clazz);
+        this.limitRows = limitRows;
+    }
+
+    public boolean hasNext() {
+        return (data.size() > cursor.get() + 1);
+    }
+
+    public RowInfo<T> next() {
+        return data.get(cursor.incrementAndGet());
+    }
+
+    @Override
+    @SneakyThrows
+    public void invoke(List<String> object, AnalysisContext context) {
+        if (limitRows > 0 && data.size() >= limitRows) {
+            limitExecuted = true;
+            return;
+        }
+        T resultModel = headProperty.getHeadClazz().newInstance();
+        RowInfo<T> rowInfo = new RowInfo<>(this, context.getCurrentRowNum(), resultModel);
+        data.add(rowInfo);
+
+        //转换制类型
+        Map map = new HashMap();
+        for (int i = 0; i < object.size(); i++) {
+            ExcelColumnProperty columnProperty = headProperty.getExcelColumnProperty(i);
+            if (columnProperty != null) {
+
+                try {
+                    Object value = TypeUtil.convert(object.get(i), columnProperty.getField(),
+                            columnProperty.getFormat(), context.use1904WindowDate());
+                    if (value != null) {
+                        map.put(columnProperty.getField().getName(), value);
+                    }
+                } catch (Exception e) {
+
+                    log.error("格式错误", e);
+
+                    //填充错误值
+                    rowInfo.errorValue(columnProperty.getField().getName(), object.get(i));
+
+                    //写入错误异常
+                    if (e instanceof NumberFormatException) {
+                        rowInfo.errorInColumn(columnProperty.getField().getName(), "数据格式错误");
+
+                    } else {
+                        rowInfo.errorInColumn(columnProperty.getField().getName(), e.toString());
+                    }
+                }
+            }
+        }
+
+        BeanMap.create(resultModel).putAll(map);
+
+        if (!rowInfo.hasError()) {
+            //执行注解校验
+            ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
+            Validator validator = vf.getValidator();
+            Set<ConstraintViolation<T>> set = validator.validate(resultModel);
+            for (ConstraintViolation<T> constraintViolation : set) {
+                rowInfo.errorInColumn(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+
+    }
+
+    public void begin() {
+        finish();
+    }
+
+    public void finish() {
+        if (globalError.size() > 0) {
+            throw new RuntimeException("无法导入," + globalError.get(0));
+        }
+
+        if (this.data.size() <= 0) {
+            error("空表格,没有任何数据!");
+        }
+
+        if (limitExecuted) {
+            error("不能超过" + limitRows + "行, 请分批导入!");
+        }
+
+        if (globalError.size() > 0) {
+            throw new RuntimeException("无法导入," + globalError.get(0));
+        }
+
+        for (val rowInfo : data) {
+            if (rowInfo.hasError()) {
+                throw new RuntimeException("无法导入, excel" + rowInfo.excelRowNum + "行有异常");
+            }
+        }
+    }
+
+    public ExcelHeadProperty2 getHead() {
+        return headProperty;
+    }
+
+    /**
+     * 标记全局异常(不是在行、不是在值上的错误)
+     */
+    public void error(String msg) {
+        errorCount.incrementAndGet();
+        globalError.add(msg);
+    }
+
+    public static class RowInfo<T> {
+
+        private T data;
+        private int excelRowNum;
+        private final ExcelDataReader<T> parent;
+        private final Map<String, String> errorValue = Maps.newLinkedHashMap();
+        private final Map<String, List<String>> errorInColumn = Maps.newLinkedHashMap();
+        private boolean error = false;
+
+        private RowInfo(ExcelDataReader<T> parent, int excelRowNum, T data) {
+            this.parent = parent;
+            this.excelRowNum = excelRowNum;
+            this.data = data;
+        }
+
+        /**
+         * 标记该行数据有错误
+         */
+        public void errorInRow(String msg) {
+            errorInColumn("row_error", msg);
+        }
+
+        /**
+         * 标记该行,某列数据有错误
+         */
+        public void errorInColumn(String columnName, String msg) {
+            error = true;
+            parent.errorCount.incrementAndGet();
+            List<String> errors = errorInColumn.get(columnName);
+            if (errors == null) {
+                errors = Lists.newArrayList();
+                errorInColumn.put(columnName, errors);
+            }
+            errors.add(msg);
+        }
+
+        /**
+         * 记录异常的数据(因为实体类有可能接受不了该数据,用Map来存储数据)
+         */
+        public void errorValue(String columnName, String value) {
+            errorValue.put(columnName, value);
+        }
+
+        /**
+         * 判断该行是否有异常
+         */
+        public boolean hasError() {
+            return error;
+        }
+
+        public int getExcelRowNum() {
+            return excelRowNum;
+        }
+
+        public T getData() {
+            return data;
+        }
+    }
+
+    /**
+     * 构造错误窗口
+     */
+    @SneakyThrows
+    public List<Map<String, Object>> buildErrorRows() {
+        List list = Lists.newArrayList();
+
+        for (RowInfo<T> rowInfo : this.data) {
+            //过滤没有错误的行
+            if (!rowInfo.hasError())
+                continue;
+
+            //只显示固定数量的行
+            if (list.size() >= ERROR_ROWS_LIMIT) {
+                continue;
+            }
+
+            //序列化行数据
+            JsonWapper jw = new JsonWapper(rowInfo.data);
+
+            //写入 excel 行号
+            jw.set("excelRowNum", rowInfo.getExcelRowNum() + 1);
+
+            //写入异常原因
+            jw.set("errorCollection", rowInfo.errorInColumn);
+
+            //合并错误值
+            for (Map.Entry<String, String> entry : rowInfo.errorValue.entrySet()) {
+                jw.set(entry.getKey(), entry.getValue());
+            }
+
+            list.add(jw.getInnerMap());
+        }
+
+        return list;
+    }
+
+    public List<String> getGlobalError() {
+        return globalError;
+    }
+
+    public int getSuccessRows() {
+        return this.successRows.get();
+    }
+
+    public void markSuccess() {
+        this.successRows.incrementAndGet();
+    }
+
+    public Object getBizData() {
+        return bizData;
+    }
+
+    public int getErrorCount() {
+        return errorCount.get();
+    }
+
+    public void setBizData(Object bizData) {
+        this.bizData = bizData;
+    }
+}

+ 94 - 0
whepi-web/src/main/java/com/bofeng/excel/ExcelHeadProperty2.java

@@ -0,0 +1,94 @@
+package com.bofeng.excel;
+
+import com.alibaba.excel.annotation.ExcelColumnNum;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.ExcelColumnProperty;
+import com.google.common.collect.Lists;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+public class ExcelHeadProperty2<T> {
+
+    private final Class<T> headClazz;
+    private final List<List<String>> head;
+    private List<ExcelColumnProperty> columnPropertyList = Lists.newArrayList();
+    private Map<Integer, ExcelColumnProperty> excelColumnPropertyMap1 = new HashMap<Integer, ExcelColumnProperty>();
+
+    public ExcelHeadProperty2(Class<T> headClazz) {
+        this.headClazz = headClazz;
+        Field[] fields = this.headClazz.getDeclaredFields();
+        List<List<String>> headList = new ArrayList<List<String>>();
+        for (Field f : fields) {
+            initOneColumnProperty(f);
+        }
+        //对列排序
+        Collections.sort(columnPropertyList);
+        for (ExcelColumnProperty excelColumnProperty : columnPropertyList) {
+            headList.add(excelColumnProperty.getHead());
+        }
+        this.head = headList;
+    }
+
+    public Class<T> getHeadClazz() {
+        return headClazz;
+    }
+
+    private void initOneColumnProperty(Field f) {
+        ExcelProperty p = f.getAnnotation(ExcelProperty.class);
+        ExcelColumnProperty excelHeadProperty = null;
+        if (p != null) {
+            excelHeadProperty = new ExcelColumnProperty();
+            excelHeadProperty.setField(f);
+            excelHeadProperty.setHead(Arrays.asList(p.value()));
+            excelHeadProperty.setIndex(p.index());
+            excelHeadProperty.setFormat(p.format());
+            excelColumnPropertyMap1.put(p.index(), excelHeadProperty);
+        } else {
+            ExcelColumnNum columnNum = f.getAnnotation(ExcelColumnNum.class);
+            if (columnNum != null) {
+                excelHeadProperty = new ExcelColumnProperty();
+                excelHeadProperty.setField(f);
+                excelHeadProperty.setIndex(columnNum.value());
+                excelHeadProperty.setFormat(columnNum.format());
+                excelColumnPropertyMap1.put(columnNum.value(), excelHeadProperty);
+            }
+        }
+        if (excelHeadProperty != null) {
+            this.columnPropertyList.add(excelHeadProperty);
+        }
+
+    }
+
+    public ExcelColumnProperty getExcelColumnProperty(int columnNum) {
+        return excelColumnPropertyMap1.get(columnNum);
+    }
+
+    public List<ExcelColumnProperty> getColumnPropertyList() {
+        return columnPropertyList;
+    }
+
+    public List<String> getHeadByRowNum(int rowNum) {
+        List<String> l = new ArrayList<>(head.size());
+        for (List<String> list : head) {
+            if (list.size() > rowNum) {
+                l.add(list.get(rowNum));
+            } else {
+                l.add(list.get(list.size() - 1));
+            }
+        }
+        return l;
+    }
+
+    public int getRowNum() {
+        int headRowNum = 0;
+        for (List<String> list : head) {
+            if (list != null && list.size() > 0) {
+                if (list.size() > headRowNum) {
+                    headRowNum = list.size();
+                }
+            }
+        }
+        return headRowNum;
+    }
+}

+ 354 - 0
whepi-web/src/main/java/com/bofeng/excel/ExcelUtils.java

@@ -0,0 +1,354 @@
+package com.bofeng.excel;
+
+import cn.afterturn.easypoi.excel.ExcelExportUtil;
+import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
+import com.alibaba.excel.EasyExcelFactory;
+import com.alibaba.excel.metadata.Sheet;
+import com.google.common.base.Strings;
+import com.yvan.PageDb;
+import com.yvan.platform.Conv;
+import com.yvan.platform.JsonWapper;
+import com.yvan.springmvc.HttpParameterParser;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public class ExcelUtils {
+
+    @SneakyThrows
+    public static void exportTemplate(String path, JsonWapper data, HttpServletResponse resp) {
+        TemplateExportParams params = new TemplateExportParams(path);
+
+        Workbook workbook = ExcelExportUtil.exportExcel(params, (Map<String, Object>) data.getInnerMap());
+        try (OutputStream fos = resp.getOutputStream()) {
+            workbook.write(fos);
+        }
+    }
+
+    public static <T> ExcelBuilder writeSheet(Class<T> clazz, List<T> data, String sheetName) {
+        return new ExcelBuilder().writeSheet(clazz, data, sheetName);
+    }
+
+    public static <T> ExcelBuilder writeSheet(Class<T> clazz, List<T> data) {
+        return new ExcelBuilder().writeSheet(clazz, data);
+    }
+
+    public static boolean isRequireTemplate(HttpServletRequest req) {
+        return "template".equals(req.getParameter("action"));
+    }
+
+    @SneakyThrows
+    public static <T> ExcelDataReader<T> getReader(Class<T> clazz, HttpServletRequest req, int limitRows) {
+        ExcelDataReader<T> reader = new ExcelDataReader<>(clazz, limitRows);
+
+        StandardMultipartHttpServletRequest request = (StandardMultipartHttpServletRequest) req;
+        MultipartFile excel = request.getFile("file");
+        reader.FILE_NAME = excel.getOriginalFilename();
+
+        try (InputStream is = excel.getInputStream();
+             BufferedInputStream bis = new BufferedInputStream(is)) {
+
+            try {
+                EasyExcelFactory.readBySax(bis, new Sheet(1, reader.getHead().getRowNum()), reader);
+            } catch (Exception e) {
+                log.error("导入无效文件", e);
+                reader.error("无效文件");
+            }
+        }
+
+        req.setAttribute(ExcelDataReader.ATTRIB_NAME, reader);
+        return reader;
+    }
+
+    @SneakyThrows
+    public static <T> void writeSuccess(ExcelDataReader<T> reader,
+                                        HttpServletRequest req,
+                                        HttpServletResponse resp) {
+        JsonWapper jw = new JsonWapper();
+        jw.set("success", true);
+        jw.set("data", reader.getBizData());
+        jw.set("msg", "成功导入" + reader.getSuccessRows() + "行.");
+
+        writeToResponse(resp, "application/json;charset=utf-8", jw.toString());
+        req.removeAttribute(ExcelDataReader.ATTRIB_NAME);
+    }
+
+    @SneakyThrows
+    public static boolean writeError(HttpServletRequest request, HttpServletResponse resp) {
+        ExcelDataReader reader = (ExcelDataReader<?>) request.getAttribute(ExcelDataReader.ATTRIB_NAME);
+        if (reader != null) {
+
+            val data = reader.buildErrorRows();
+            if (data.size() > 0 || reader.getGlobalError().size() > 0) {
+                JsonWapper jw = new JsonWapper();
+                jw.set("success", false);
+                jw.set("data", data);
+                jw.set("error", reader.getGlobalError());
+                if (reader.getGlobalError().size() > 0) {
+                    //全局错误
+                    StringBuilder sb = new StringBuilder();
+                    for (val s : reader.getGlobalError()) {
+                        sb.append(s.toString() + '.');
+                    }
+                    jw.set("msg", sb.toString() + "本次导入无效");
+
+                } else if (data.size() > 0) {
+                    jw.set("msg", "存在" + reader.getErrorCount() + "个错误,本次导入无效(数据不会发生变化),请核对后重新导入");
+
+                } else {
+                    jw.set("msg", "本次导入无效(数据不会发生变化),请核对后重新导入");
+                }
+
+                writeToResponse(resp, "application/json;charset=utf-8", jw.toString());
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public static final String TOKEN_KEY = "TOKEN";
+    public static final Charset UTF8 = Charset.forName("UTF-8");
+
+    public static HttpServletRequest currentRequest() {
+        try {
+            return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
+                    .getRequest();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static HttpServletResponse currentResponse() {
+        try {
+            return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
+                    .getResponse();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static String currentRemoteIp() {
+        HttpServletRequest request = currentRequest();
+        if (request == null) {
+            return "";
+        }
+
+        if (request.getHeader("x-forwarded-for") != null) {
+            return request.getHeader("x-forwarded-for");
+        }
+        return request.getRemoteAddr();
+    }
+
+    public static String currentHost() {
+        HttpServletRequest request = currentRequest();
+        if (request == null) {
+            return "";
+        }
+
+        String host = request.getHeader("X-Forwarded-Host");
+        if (!Strings.isNullOrEmpty(host)) {
+            return host;
+        }
+        return request.getHeader("Host");
+    }
+
+    public static String currentUrl() {
+        HttpServletRequest request = currentRequest();
+        if (request == null) {
+            return "";
+        }
+
+        return request.getScheme() + "://" + currentHost() + request.getRequestURI();
+    }
+
+    public static boolean isEqualPath(String s1, String s2) {
+        if (Strings.isNullOrEmpty(s1) || Strings.isNullOrEmpty(s2)) {
+            return false;
+        }
+
+        int p1 = s1.indexOf("?");
+        if (p1 >= 0) {
+            s1 = s1.substring(0, p1);
+        }
+        int p2 = s2.indexOf("?");
+        if (p2 >= 0) {
+            s2 = s2.substring(0, p1);
+        }
+        return s1.toLowerCase().equals(s2.toLowerCase());
+    }
+
+    public static String currentToken() {
+        HttpServletRequest request = currentRequest();
+        if (request == null) {
+            return "";
+        }
+
+        String token;
+        // 从head取
+        token = request.getHeader(TOKEN_KEY);
+        if (!Strings.isNullOrEmpty(token)) {
+            return token;
+        }
+
+        // 从attribute取
+        token = request.getAttribute(TOKEN_KEY).toString();
+        if (!Strings.isNullOrEmpty(token)) {
+            return token;
+        }
+
+        // 从cookie取
+        token = getCookieValue(TOKEN_KEY);
+        if (!Strings.isNullOrEmpty(token)) {
+            return token;
+        }
+
+        return null;
+    }
+
+    public static void writeToken(String token) {
+        Cookie cookie = new Cookie(TOKEN_KEY, token);
+        cookie.setPath("/");
+        writeCookie(cookie);
+    }
+
+    /**
+     * 请求是否需要被拦截
+     */
+    public static boolean isFilterPass(HttpServletRequest httpRequest) {
+        String thisUrl = httpRequest.getRequestURI();
+        return (thisUrl.startsWith("/static/") ||
+                thisUrl.startsWith("/manage/") ||
+                thisUrl.startsWith("/druid/") ||
+                thisUrl.startsWith("/igh2/") ||
+                thisUrl.endsWith(".css") || thisUrl.endsWith(".jpg") || thisUrl.endsWith(".jpeg") ||
+                thisUrl.endsWith(".html") || thisUrl.endsWith(".js") || thisUrl.endsWith(".png") ||
+                thisUrl.endsWith(".gif") || thisUrl.endsWith(".map"));
+    }
+
+    /**
+     * 从当前请求中获取分页方法和内容
+     */
+    public static PageDb parsePagination() {
+        HttpServletRequest request = currentRequest();
+        HttpParameterParser parser = HttpParameterParser.newInstance(request);
+        int page = parser.getIntValue("page", 1);
+        int start = parser.getIntValue("start", 0);
+        int limit = parser.getIntValue("limit", 10);
+
+        return new PageDb(page, limit);
+    }
+
+
+    /**
+     * 得到当前request请求的所有cookie
+     */
+    public static Cookie[] getCookies() {
+        HttpServletRequest request = currentRequest();
+        return request == null ? null : request.getCookies();
+    }
+
+    /**
+     * 根据cookie名字取得cookie
+     */
+    public static Cookie getCookie(String name) {
+        Cookie[] cookies = getCookies();
+        if (cookies != null && cookies.length > 0) {
+            for (int i = 0; i < cookies.length; i++) {
+                Cookie cookie = cookies[i];
+                String cookName = cookie.getName();
+                if (cookName != null && cookName.equals(name)) {
+                    return cookie;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static String getCookieValue(String name) {
+        Cookie cookie = getCookie(name);
+        if (cookie == null) {
+            return null;
+        }
+        return cookie.getValue();
+    }
+
+    /**
+     * 将cookie写入客户端
+     */
+    public static void writeCookie(Cookie cookie) {
+        if (cookie == null) {
+            return;
+        }
+        HttpServletResponse response = currentResponse();
+
+        /*
+         * if (request != null) { String host = request.getHeader("Host"); if (ConfigUtils.WEBSITE.equals(host))
+         * cookie.setDomain("." + ConfigUtils.DOMAIN); }
+         */
+        if (response != null) {
+            response.addCookie(cookie);
+        }
+    }
+
+    public static void removeCookie(String cookieName, String path) {
+
+        HttpServletResponse response = currentResponse();
+        HttpServletRequest request = currentRequest();
+
+        Cookie[] cookies = request.getCookies();
+        if (cookies == null || cookies.length == 0) {
+            return;
+        }
+
+        for (int i = 0; i < cookies.length; i++) {
+            Cookie cookie = cookies[i];
+            if (cookie.getName().equals(cookieName)) {
+                cookie.setMaxAge(0);
+                cookie.setPath(path);
+                response.addCookie(cookie);
+                break;
+            }
+        }
+
+    }
+
+    public static String urlEncoding(String value) {
+        try {
+            byte[] bs = Base64.encodeBase64URLSafe(value.getBytes("UTF-8"));
+            return new String(bs, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("encode error.", e);
+        }
+    }
+
+    @SneakyThrows
+    public static void writeToResponse(HttpServletResponse response, String contentType, String json) {
+        response.setContentType(contentType);
+        response.setHeader("Cache-Control", "no-cache");
+        response.setHeader("Expires", "0");
+        response.setHeader("Pragma", "No-cache");
+        response.setContentLength(json.getBytes(UTF8).length);
+        PrintWriter out = response.getWriter();
+        if (out != null) {
+            out.print(json);
+            out.flush();
+            out.close();
+        }
+    }
+}

+ 12 - 0
whepi-web/src/main/java/com/bofeng/wx/controller/UserOpenController.java

@@ -2,12 +2,15 @@ package com.bofeng.wx.controller;
 
 import com.bofeng.dao.*;
 import com.bofeng.entity.*;
+import com.bofeng.excel.ExcelUtils;
 import com.bofeng.service.*;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.yvan.platform.JsonWapper;
 import com.yvan.platform.YvanUtil;
 import com.yvan.springmvc.ResultModel;
 import io.swagger.annotations.*;
+import lombok.SneakyThrows;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -17,6 +20,7 @@ import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.servlet.ModelAndView;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -146,4 +150,12 @@ public class UserOpenController {
         String doorplate = request.getParameter("doorplate");
         userOpenService.saveUserInfo(userId,userType,linkman,phone,area,uptownId,unitId,doorplate);
     }
+
+    @ApiOperation("客户档案信息错误数据导出")
+    @GetMapping("/user/importExcelUserOpen")
+    @SneakyThrows
+    public void errorCustInfo(HttpServletResponse resp) {
+        List<UserOpen> list = userOpenMapper.getAllUser();
+        ExcelUtils.writeSheet(UserOpen.class, list).export(resp);
+    }
 }

+ 4 - 0
whepi-web/src/main/resources/mapper/UserOpen.xml

@@ -15,4 +15,8 @@
         select * from sys_user_open
         where open_id=#{openId}
     </select>
+
+    <select id="getAllUser" resultType="com.bofeng.entity.UserOpen">
+        select * from sys_user_open
+    </select>
 </mapper>

+ 4 - 0
yvan-platform/build.gradle

@@ -31,6 +31,10 @@ dependencies {
     compile 'org.springframework.boot:spring-boot-starter-freemarker'
     compile 'io.springfox:springfox-swagger2:2.9.2'
     compile 'io.springfox:springfox-swagger-ui:2.9.2'
+    compile group: 'com.alibaba', name: 'easyexcel', version: '1.1.2-beta5'
+    compile 'cn.afterturn:easypoi-base:4.1.0'
+    compile 'cn.afterturn:easypoi-web:4.1.0'
+    compile 'cn.afterturn:easypoi-annotation:4.1.0'
 }
 
 artifacts {