一:自定义数据类型
public class AmountType extends AbstractNumberTypeCodec<String> {
@Override
protected String doSerialize(String field, FileColumnMeta columnMeta) {
return field;
}
@Override
protected String doDeserialize(String field, FileColumnMeta columnMeta) {
return null;
}
@Override
public String add(String a, String b) {
if (a == null && b == null) {
return "0";
}
if (a == null) {
return b;
}
if (b == null) {
return a;
}
return new BigDecimal(a).add(new BigDecimal(b)).toPlainString();
}
}
为自定义类型定义一个简称。
src/main/resources/META-INF/rdf-file/services/com.alipay.rdf.file.spi.RdfFileColumnTypeSpi
Amount,amount=com.example.rdffile.type.AmountType
二:自定义格式化
/**
* 处理数值类型,保留小数点,并占用一位长度
*/
public class PColumnFormat implements RdfFileFormatSpi {
@Override
public String serialize(String field, FileColumnMeta columnMeta, FileConfig fileConfig) {
int leftAttr = columnMeta.getRange().getFirstAttr() - columnMeta.getRange().getSecondAttr();
// 空补0
if (RdfFileUtil.isBlank(field)) {
field = RdfFileUtil.alignRight("", leftAttr, "0");
if (columnMeta.getRange().getSecondAttr() > 0) {
field = field.substring(1);
field = field + "." + RdfFileUtil.alignLeft("", columnMeta.getRange().getSecondAttr(), "0");
}
return field;
} else {
// 有小数点
if (field.contains(".")) {
String[] fields = field.split("\\.");
String leftStr = fields[0];
String rightStr = fields[1];
field = RdfFileUtil.alignRight(leftStr, leftAttr, "0");
if (columnMeta.getRange().getSecondAttr() <= 0) {
return field;
}
if (RdfFileUtil.isBlank(rightStr) || columnMeta.getRange().getSecondAttr() > rightStr.length()) {
field = field.substring(1) + "." + RdfFileUtil.alignLeft(RdfFileUtil.isBlank(rightStr) ? "" : rightStr, columnMeta.getRange().getSecondAttr(), "0");
} else {
field = field.substring(1) + "." + rightStr.substring(0, columnMeta.getRange().getSecondAttr());
}
} else {
// 无小数点
field = RdfFileUtil.alignRight(field, leftAttr, "0");
if (columnMeta.getRange().getSecondAttr() <=0) {
return field;
}
field = field.substring(1) + "." + RdfFileUtil.alignLeft("", columnMeta.getRange().getSecondAttr(), "0");
}
}
return field;
}
@Override
public String deserialize(String field, FileColumnMeta columnMeta, FileConfig fileConfig) {
return field.trim();
}
}
为数据格式化定义一个简称。
src/main/resources/META-INF/rdf-file/services/com.alipay.rdf.file.spi.RdfFileFormatSpi
P=com.example.rdffile.format.PColumnFormat
三:自定义汇总
public class AmountSummaryPair extends AbstractSummaryPair<String> {
@Override
protected void doAddColValue(String columnValue) {
summaryValue = new BigDecimal(summaryValue).add(new BigDecimal(columnValue)).toPlainString();
}
@Override
public String initDefaultColumnValue() {
return "0";
}
}
定义那些类型字段使用汇总。
src/main/resources/META-INF/rdf-file/services/com.alipay.rdf.file.spi.RdfFileSummaryPairSpi
Amount,amount=com.example.rdffile.summary.AmountSummaryPair
四:fund.properties
数据类型和格式化绑定。新增Amount=P。
DigitalChar=A
String=C
Date=C
Boolean=N
BigDecimal=N
Integer=N
Long=N
Float=N
Double=N
Amount=P
五:模板
Price的数据类型定义为Amount,相应的格式化、汇总也要配套。
{
"head":[
"identity|信息标识|[8,0]|default:OFDCFDAT",
"version|协议版本号|[4,0]|default:20",
"msgCreator|信息创建人|[9,0]|default:H0",
"msgRecipient|信息接收人|[9,0]",
"sendDate|传送发生日期|[8,0]|Date:yyyyMMdd",
"summaryTableNo|汇总表号|[3,0]",
"fileTypeCode|文件类型代码 |[2,0]",
"sender|发送人|[8,0]|default:H0",
"recipient|接收人|[8,0]",
"totalPrice|总金额|Amount|[16,2]|Required"
],
"body":[
"TransactionCfmDate|对帐日期|[8,0]|Date:yyyyMMdd",
"FundCode|基金代码|[8,0]",
"AvailableVol|基金可用份数|BigDecimal|[6,2]",
"Price|价格|Amount|[16,2]",
"isVip|是否VIP|Boolean|[6,0]"
],
"tail":[
"fileEnd|数据文件尾部字符|default:OFDCFEND|[8,0]"
],
"protocol":"fund"
}
六:写文件
String path = new ClassPathResource("").getFile().getPath();
String filePath = new File(path, "fund_write.txt").getAbsolutePath();
FileConfig config = new FileConfig(filePath, "templates/template6.json", new StorageConfig("nas"));
FileWriter fileWriter = FileFactory.createWriter(config);
Map<String, Object> head = new HashMap<String, Object>();
head.put("msgRecipient", "xxx");
head.put("sendDate", "20231122");
head.put("summaryTableNo", "aa");
head.put("fileTypeCode", "bb");
head.put("recipient", "ll");
head.put("totalCount", 1);
head.put("totalPrice", "8888888");
fileWriter.writeHead(head);
Map<String, Object> row = new HashMap<String, Object>();
row.put("TransactionCfmDate", "20231122");
row.put("FundCode", "中国1");
row.put("AvailableVol", BigDecimal.valueOf(42.11));
row.put("Price", "888.66");
row.put("isVip", true);
fileWriter.writeRow(row);
fileWriter.writeTail(new HashMap<>());
fileWriter.close();
OFDCFDAT
20
H0
xxx
20231122
aa
bb
H0
ll
0000008888888.00
005
TransactionCfmDate
FundCode
AvailableVol
Price
isVip
00000001
20231122中国1 0042110000000000888.66true
OFDCFEND