Backend —— "Enregistrez une démo qui a exporté un fichier txt en fonction du modèle

Cet article n'a pas de points techniques particuliers. Si vous insistez pour dire quelque chose, il peut s'agir des trois points suivants, le plus important étant abstrait

1. Résumé

2. Réflexion

3. Fonctionnement IO

 

1. Créez un nouvel objet de génération de fichier, qui est principalement utilisé pour prendre le chemin du fichier temporaire

public class GenteraterRetunData {

  private String localFilePath;

  public GenteraterRetunData(String localFilePath) {
    this.localFilePath = localFilePath;
  }

  public String getLocalFilePath() {
    return localFilePath;
  }

  public void setLocalFilePath(String localFilePath) {
    this.localFilePath = localFilePath;
  }
}

2. Créez une interface de classe de base générée par un fichier txt

import com.xxx.entity.PolicyLeads;
import com.xxx.submit.model.GenteraterRetunData;
import java.util.List;

/**
 * Created by dearx on 2019/12/19
 */
public interface TxtBaseGenerater {

  GenteraterRetunData generate(List<PolicyLeads> policyLeads, String fileName) throws Exception;

}

3. Créez une classe de génération de fichier txt pour implémenter l'interface de classe de base TxtBaseGenerater. Cette classe est principalement utilisée pour générer des fichiers. Chemin de génération de fichier, fileDist J'utilise l'injection. PolicyLeads est une classe d'entité, je n'entrerai donc pas dans les détails

import com.xxx.entity.PolicyLeads;
import com.xxx.submit.model.GenteraterRetunData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by dearx on 2019/12/19
 */

public abstract class TxtWorkBookGenerater implements TxtBaseGenerater {

    protected Logger logger = LoggerFactory.getLogger(TxtWorkBookGenerater.class);

    @Value("${local.file.path}")
    public  String fileDist;

    /*获取txt表头的map,map中的key如果是policy表的字段名,可直接获取字段值。如果不是字段名,可以再子类继承后自定义*/
    abstract public Map<String, String> getHearMap();

    /*获取txt文件的内容*/
    abstract public String getContent(PolicyLeads policyLeads,String headKey);

    /*获取txt文件每行各个字段隔开的符号标识*/
    abstract public String getSplitSymbol();

    @Override
    public GenteraterRetunData generate(List<PolicyLeads> policyLeadsList, String fileName) throws Exception {
        /*拼接表头*/
        StringBuffer  hearStr=new StringBuffer();
        getHearMap().forEach((k, v) -> {
            if("".equals(hearStr.toString())){
                hearStr.append(v);
            }else{
                hearStr.append(getSplitSymbol()+v);
            }
        });
        logger.info("txt文件表头为 【{}】",hearStr.toString());
       /*创建一个文件,File.separator 是为了适应windows和linux不同的文件夹分隔符*/
        File file = new File(fileDist + File.separator + fileName+".txt");
        logger.info("txt文件【{}】创建成功",file.getAbsolutePath());
        /*给文件填充内容*/
        exportTxt(file, policyLeadsList, hearStr.toString());
        logger.info("txt文件【{}】生成成功",file.getAbsolutePath());
        /*返回文件路径*/
        return new GenteraterRetunData(file.getAbsolutePath());
    }


    /**
     * 导出
     *
     * @param file  Txt文件(路径+文件名),Txt文件不存在会自动创建
     * @param heads 表头
     * @return
     * @author [email protected]
     * @create 2016-4-27 上午9:49:49
     */
    public void exportTxt(File file, List<PolicyLeads> policyLeadsList, String heads) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            List<String> contenList = new ArrayList<>();
            /*这个for循环主要用来根据表头拼接内容*/
            for (PolicyLeads policyLeads : policyLeadsList) {
                /*每行的内容*/
                StringBuffer content = new StringBuffer();
                /*遍历静态表头的map*/
                getHearMap().forEach((headKey, headkValue) -> {
                    Boolean hashead = false;
                    /*遍历此次导出的表头*/
                    for (String hearName : heads.split(getSplitSymbol())) {
                        /*如果静态表头中包含此次导出的表头,退出循环,使hashead=true*/
                        if (headkValue .equals(hearName) ) {
                            hashead = true;
                            break;
                        }
                    }
                    /*如果hashead=true,表示需要把这个字段加入到导出文件中*/
                    if (hashead) {
                        /*获取这个字段的值*/
                        String data = getContent(policyLeads,headKey);
                        /*将字段的值拼接到这一行*/
                        content.append("".equals(content.toString()) ? data : getSplitSymbol() + data);
                    }
                });
                contenList.add(content.toString());
            }

            if (exportTxtByOS(out, contenList, heads)) {
                logger.info("文件【{}】文件流写入成功", file.getName(), file.getParent());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            logger.info(e.getStackTrace().toString());
        }
    }

    /**
     * 导出
     * @param out      输出流
     * @param dataList 内容数据
     * @param heads    表头
     */
    public static boolean exportTxtByOS(OutputStream out, List<String> dataList, String heads) {
        boolean isSucess = false;

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            osw = new OutputStreamWriter(out);
            bw = new BufferedWriter(osw);
            //循环表头
            if (heads != null && !heads.equals("")) {
                bw.append(heads).append("\r");
            }
            //循环数据
            if (dataList != null && !dataList.isEmpty()) {
                for (String data : dataList) {
                    bw.append(data).append("\r");
                }
            }
            isSucess = true;
        } catch (Exception e) {
            e.printStackTrace();
            isSucess = false;
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                    bw = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (osw != null) {
                try {
                    osw.close();
                    osw = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                    out = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return isSucess;
    }


}

4. Créez une classe de modèle de fichier pour hériter de la classe de génération de fichier. S'il existe plusieurs modèles différents, créez simplement quelques autres classes de modèles et modifiez la méthode abstraite de la classe parente dans la sous-classe

import com.xxx.common.utils.MethodUtil;
import com.xxx.common.utils.StringUtil;
import com.xxx.entity.PolicyLeads;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by dearx on 2019/12/19
 */
@Component("SampleTxt")
public class SampleTxtGenerater extends TxtWorkBookGenerater {

    protected Logger logger = LoggerFactory.getLogger(SampleTxtGenerater.class);

    @Override
    public Map<String, String> getHearMap() {
        /*LinkedHashMap便于按顺序写入表头*/
        Map<String, String> hearMap = new LinkedHashMap<>();
        hearMap.put("name", "姓名");
        hearMap.put("age", "年龄");
        hearMap.put("mobile", "手机号");
        hearMap.put("source", "数据类型");
        return hearMap;
    }

    @Override
    public String getContent(PolicyLeads policyLeads, String headKey) {
        String data = "";
        try {
            if ("source".equals(headKey)) {
                /*做了特别判断的,如source,代表是自定义的字段,通过各字段值组合拼接而成*/
                String dataSourceName = policyLeads.getCompanyDataSource() != null ? policyLeads.getCompanyDataSource().getDataSourceName() : "";
                String dataType = policyLeads.getDataPipe().getDataType().getTypeName();
                data = dataSourceName + "-" + dataType;
            } else {
                /*没有做特别判断的表示该字段是policyleads实体中的字段,通过反射获取字段值*/
                data = StringUtil.safeToString(MethodUtil.getGetMethod(policyLeads, headKey), "");
            }
            return data;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e.getStackTrace().toString());
            logger.info(e.getMessage().toString());
            return "";
        }
    }

    @Override
    public String getSplitSymbol() {
        return ",";
    }
}

5. Les outils utilisés dans le code ci-dessus sont principalement des outils réfléchissants.

import java.lang.reflect.Method;
import java.math.BigDecimal;
public class MethodUtil {
    /**
     * 根据属性,获取get方法
     * @param ob 对象
     * @param name 属性名
     * @return
     * @throws Exception
     */
    public static Object getGetMethod(Object ob , String name)throws Exception{
        Method[] m = ob.getClass().getMethods();
        for(int i = 0;i < m.length;i++){
            if(("get"+name).toLowerCase().equals(m[i].getName().toLowerCase())){
                return m[i].invoke(ob);
            }
        }
        return null;
    }

    /**
     * 根据属性,拿到set方法,并把值set到对象中
     * @param obj 对象
     * @param clazz 对象的class
     * @param typeClass
     * @param value
     */
    public static void setValue(Object obj,Class<?> clazz,String filedName,Class<?> typeClass,Object value){
        filedName = removeLine(filedName);
        String methodName = "set" + filedName.substring(0,1).toUpperCase()+filedName.substring(1);
        try{
            Method method =  clazz.getDeclaredMethod(methodName, new Class[]{typeClass});
            method.invoke(obj, new Object[]{getClassTypeValue(typeClass, value)});
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

    /**
     * 通过class类型获取获取对应类型的值
     * @param typeClass class类型
     * @param value 值
     * @return Object
     */
    private static Object getClassTypeValue(Class<?> typeClass, Object value){
        if(typeClass == int.class  || value instanceof Integer){
            if(null == value){
                return 0;
            }
            return value;
        }else if(typeClass == short.class){
            if(null == value){
                return 0;
            }
            return value;
        }else if(typeClass == byte.class){
            if(null == value){
                return 0;
            }
            return value;
        }else if(typeClass == double.class){
            if(null == value){
                return 0;
            }
            return value;
        }else if(typeClass == long.class){
            if(null == value){
                return 0;
            }
            return value;
        }else if(typeClass == String.class){
            if(null == value){
                return "";
            }
            return value;
        }else if(typeClass == boolean.class){
            if(null == value){
                return true;
            }
            return value;
        }else if(typeClass == BigDecimal.class){
            if(null == value){
                return new BigDecimal(0);
            }
            return new BigDecimal(value+"");
        }else {
            return typeClass.cast(value);
        }
    }

    /**
     * 处理字符串  如:  abc_dex ---> abcDex
     * @param str
     * @return
     */
    public static  String removeLine(String str){
        if(null != str && str.contains("_")){
            int i = str.indexOf("_");
            char ch = str.charAt(i+1);
            char newCh = (ch+"").substring(0, 1).toUpperCase().toCharArray()[0];
            String newStr = str.replace(str.charAt(i+1), newCh);
            String newStr2 = newStr.replace("_", "");
            return newStr2;
        }
        return str;
    }

}

6. Appelez.

  6.1, Comment obtenir le printemps

  

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Created by dearx on 2019/12/19.
 */
@Component
public class SpringUtils implements ApplicationContextAware {
  
  private static ApplicationContext applicationContext = null;


  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    if (SpringUtils.applicationContext == null) {
      SpringUtils.applicationContext = applicationContext;
    }
  }
  
  // 获取applicationContext
  public static ApplicationContext getApplicationContext() {
    return applicationContext;
  }
  
  // 通过name获取Bean
  public static Object getBean(String name) {
    return getApplicationContext().getBean(name);
  }
  
  // 通过class获取Bean
  public static <T> T getBean(Class<T> clazz) {
    return getApplicationContext().getBean(clazz);
  }
  
  // 通过name以及Clazz返回指定的Bean
  public static <T> T getBean(String name, Class<T> clazz) {
    return getApplicationContext().getBean(name, clazz);
  }


}

6.2, appeler

 /*SampleTxt是bean的名称,就当做是模板code,就是上面的SampleTxtGenerater类通过@Component注解注入
  *SampleTxt可以自定义,比如A模板,就可以叫ATxt,B模板可以交BTxt。
  *通过模板code获取到相应的文件生成类/  
TxtBaseGenerater txtgenerater = (TxtBaseGenerater) SpringUtils.getBean("SampleTxt");
/* 调用生成方法,第一个参数传数据list,第二个参数传文件名称*/
  txtgenerater.generate(entityList, filename);

fin------

Je suppose que tu aimes

Origine blog.csdn.net/nienianzhi1744/article/details/103630132
conseillé
Classement