Epidata数据构建工具

之前版本存在问题,现已修复

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @Description TODO
 * @Date 2023/1/4 10:14
 * @Author Shixy
 */
@Slf4j
@Getter
public class EpidataUtils {

    private List<String> lines;

    private StringBuilder line;

    private static final int LINE_MAX_LENGTH = 78;
    private static final String CHINESE_REGEX = "[^\\x00-\\xff]+";
    private static final String SPACE = " ";
    private static final String END_SYMBOL = "!";
    private static final String GBK = "GBK";

    private EpidataUtils() {
    }

    public static EpidataUtils getInstance() {
        EpidataUtils epidataUtils = new EpidataUtils();
        epidataUtils.lines = new ArrayList<>();
        epidataUtils.line = new StringBuilder();
        return epidataUtils;
    }

    public void append(String str) {
        try {
            int lineLength = line.toString().getBytes(GBK).length;
            int strLength = str.getBytes(GBK).length;

            int negative = 0;

            if (lineLength + strLength > LINE_MAX_LENGTH) {
                String subContent = stingLenProcessOk(str, LINE_MAX_LENGTH - lineLength);
                int subContentByteLength = getByteLength(subContent);
                // 若该行字符长度不等于78,则
                if (subContent.getBytes(GBK).length + lineLength != LINE_MAX_LENGTH) {
                    subContent = " " + subContent;
                    negative = 1;
                }

                line.append(subContent);
                line.append(END_SYMBOL);
                lines.add(line.toString());
                line = new StringBuilder();

                line.append(stingLenProcessOk(str, subContentByteLength, strLength - subContentByteLength - negative));
            } else if (lineLength + strLength == LINE_MAX_LENGTH) {
                line.append(str);
                line.append(END_SYMBOL);
                lines.add(line.toString());
                line = new StringBuilder();
            } else {
                line.append(str);
            }
        } catch (UnsupportedEncodingException e) {
            log.error("不支持的字符编码: ", e);
        } catch (IndexOutOfBoundsException e) {
            log.error("字符截取出错: ", e);
        }
    }

    public void appendFinish() {
        line.append(END_SYMBOL);
        lines.add(line.toString());
    }

    public static String appendSpace(String content, int length) {
        try {
            Boolean flag = Boolean.FALSE;
            int contentLength = content.getBytes(GBK).length;
            StringBuilder sb = new StringBuilder();
            if (contentLength > length) {
                return stingLenProcessOk(content, length);
//                throw new IndexOutOfBoundsException("index " + contentLength + ", max length " + length);
            }
            if (content.trim().matches(CHINESE_REGEX)) {
                sb.append(content);
                flag = Boolean.TRUE;
            }
            for (int i = 0; i < length - contentLength; i++) {
                sb.append(SPACE);
            }
            if (!flag) {
                sb.append(content);
            }
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            log.error("不支持的字符编码: ", e);
            return "";
        }
    }

    /**
     * 截取时考虑了第pLen、第pLen+1个字节为一个占两字节的字符的情况
     *
     * @param pContent
     * @param pLen
     * @return
     */
    private static String stingLenProcessOk(String pContent, int pLen) {
        String result = pContent;
        //由于JAVA的String的length是判断字符的个数,但后台数据库是根据指定编码(如GBK)保存数据的,所以JAVA的字符长度判断需根据字节判断
        if (result != null) {
            try {
                byte[] bytes = result.getBytes(GBK);

                if (bytes.length > pLen) {
                    int tempLen = new String(bytes, 0, pLen, GBK).length();
                    //根据tempLen长度截取原字符串
                    result = result.substring(0, tempLen);

                    bytes = result.getBytes(GBK);
                    //如果第totalLen、第totalLen+1个字节正好是一个汉字,String的substring方法会返回一个完整的汉字,导致长度为totalLen+1(超过totalLen),所以再次对pContent的长度进行字节判断与处理
                    if (bytes.length > pLen) {
                        result = result.substring(0, tempLen - 1);
                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private static String stingLenProcessOk(String pContent, int startB, int length) {
        String result = pContent;
        //由于JAVA的String的length是判断字符的个数,但后台数据库是根据指定编码(如GBK)保存数据的,所以JAVA的字符长度判断需根据字节判断
        if (result != null) {
            try {
                byte[] bytes = result.getBytes(GBK);
                result = new String(bytes, startB, length, GBK);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private int getByteLength(String str) {
        try {
            return str.getBytes(GBK).length;
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        Map<String, String> map = new LinkedHashMap<>();
        map.put("ID1", "xxxxxxxxxxxxxxxx");
        map.put("province", "44");
        map.put("city", "15");
        map.put("district", "2");
        map.put("county", "02");
        map.put("point", "2");
        map.put("school", "06");
        map.put("grade", "53");
        map.put("num", "0101");
        map.put("ID2", "xxxxxxxxxxxxxxxx");
        map.put("gender", "1");
        map.put("nation", "1");
        map.put("nationothe", "                    ");
        map.put("birth", "2015/09/04");
        map.put("examine", "2020/12/12");
        map.put("glasstype", "4");
        map.put("OKR", "      ");
        map.put("OKL", "      ");
        map.put("visionR", "5.0");
        map.put("glassR", "   ");
        map.put("visionL", "5.0");
        map.put("glassL", "   ");
        map.put("name2", "xxx              ");
        map.put("spherR", "  0.50");
        map.put("cylinR", " -0.25");
        map.put("axisR", "170");
        map.put("SER", "  0.375");
        map.put("spherRT", "      ");
        map.put("cylinRT", "      ");
        map.put("axisRT", "   ");
        map.put("spherL", "  0.25");
        map.put("cylinL", " -0.25");
        map.put("axisL", " 10");
        map.put("SEL", "  0.125");
        map.put("spherLT", "      ");
        map.put("cylinLT", "      ");
        map.put("axisLT", "   ");
        map.put("NOTE", "                                        ");
        map.put("name", "xxx              ");
        map.put("date", "2020/12/12");

        EpidataUtils instance = getInstance();
        map.forEach((k, v) -> {
            instance.append(v);
        });
        instance.appendFinish();
        List<String> lines1 = instance.getLines();
        lines1.forEach(System.out::println);
    }

}


posted @ 2023-01-04 15:52  云の彼端  阅读(71)  评论(0)    收藏  举报