之前版本存在问题,现已修复
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);
}
}