最近做项目有一个需要用到导出txt文件的地方,内容大概就是一个把list数据类型格式的数据导出到txt文件,但是txt的排版是一个令人头疼的事情。但是一直不知道怎么让每列对齐,所以就出现了下面这样的情况。

思路
思路其实很简单,就是跟html画表格一样,考虑到表格中的每列的宽度都是固定的。那我们导出的时候也把每列宽度都固定不就行了吗。假设每列宽度最大为20个字符,那么我们就把这一列宽度设置为20个字符,不足20的用空格填充。不多说了,下面贴代码。
package com.seemygo.shop.cloud;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Random;
public class formatStr {
public static void main(String[] args) {
addStr();
}
public static void addStr(){
// filename指定默认的名字
File file=new File("D:/data/stu.txt");
BufferedWriter bw=null;
StringBuffer write = new StringBuffer();
String tab = "\t\t";
String enter = "\r\n";
try {
//创建输出流
bw=new BufferedWriter(new FileWriter(file,true));
int length = 20;
write.append(appentStr4Length("平台订单号",length));
//write.append(tab);
write.append(appentStr4Length("商户订单号",length));
// write.append(tab);
write.append(appentStr4Length("商户批次号",length));
//write.append(tab);
write.append(appentStr4Length("账号",length));
//write.append(tab);
write.append(appentStr4Length("账户名称",length));
//write.append(tab);
write.append(appentStr4Length("账户类型",length));
//write.append(tab);
write.append(appentStr4Length("金额",length));
//write.append(tab);
write.append(appentStr4Length("状态 ",length));
//write.append(tab);
write.append(appentStr4Length("手续费",length));
//write.append(tab);
write.append(appentStr4Length("支付类型",length));
write.append(enter);
write.append("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ");
write.append(enter);
Random random = new Random();
for(int i = 0;i<10;i++){
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length)); //平台订单号
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//商户订单号
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//商户批次号
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//账号
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//账户名称
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//账户类型
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//金额
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//状态
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//手续费
//write.append(tab);
write.append(appentStr4Length(String.valueOf(random.nextInt(1000)),length));//支付类型
write.append(enter);
}
Charset charset = Charset.forName("UTF-8"); // 指定编码格式
byte[] bytes = write.toString().getBytes(charset); // 将StringBuffer转换为byte数组
// 如果需要,可以将byte数组转换回String
String encodedString = new String(bytes, charset);
bw.write(encodedString);
bw.flush();
bw.close();
} catch (Exception e) {
e.printStackTrace();
if (bw !=null){
try {
bw.close();
} catch (IOException ex) {
e.printStackTrace();
}
;
}
}finally{
System.out.println("111111111");
if (bw !=null){
try {
bw.close();;
}catch (IOException e){
e.printStackTrace();
}
}
}
}
public static String appentStr4Length(String str , int length){
if(str == null){
str = "";
}
try {
int strLen = 0;//计算原字符串所占长度,规定中文占两个,其他占一个
for(int i = 0 ; i<str.length(); i++){
if(isChinese(str.charAt(i))){
strLen = strLen + 2;
}else{
strLen = strLen + 1;
}
}
if(strLen>=length){
return str;
}
int remain = length - strLen;//计算所需补充空格长度
for(int i =0 ; i< remain ;i++){
str = str + " ";
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
// 根据Unicode编码完美的判断中文汉字和符号
private static boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
return true;
}
return false;
}
}
//大概用法
HttpServletResponse response = getHttpServletResponse();
// filename指定默认的名字
BufferedOutputStream buff = null;
StringBuffer write = new StringBuffer();
String tab = "\t\t";
String enter = "\r\n";
ServletOutputStream outStr = null;
response.setContentType("text/plain");// 一下两行关键的设置
response.addHeader("Content-Disposition",
"attachment;filename="+DateUtil.formatDateTime(DateUtil.DF_YMDHMS, new Date())+".txt");
try {
outStr = response.getOutputStream();// 建立
buff = new BufferedOutputStream(outStr);
Map<String, Object> listMap = service.getPaymentBatchDetailListById(map);
List<PaymentBatchDetailDto> resultList = new ArrayList<PaymentBatchDetailDto>();
resultList = (List<PaymentBatchDetailDto>) listMap.get("list");
int length = 20;
if (null != resultList && resultList.size() > 0) {
write.append(appentStr4Length("平台订单号",length));
//write.append(tab);
write.append(appentStr4Length("商户订单号",length));
//write.append(tab);
write.append(appentStr4Length("商户批次号",length));
//write.append(tab);
write.append(appentStr4Length("账号",30));
//write.append(tab);
write.append(appentStr4Length("账户名称",length));
//write.append(tab);
write.append(appentStr4Length("账户类型",length));
//write.append(tab);
write.append(appentStr4Length("金额",length));
//write.append(tab);
write.append(appentStr4Length("状态 ",length));
//write.append(tab);
write.append(appentStr4Length("手续费",length));
//write.append(tab);
write.append(appentStr4Length("支付类型",length));
//write.append(tab);
write.append(appentStr4Length("创建日期",length));
//write.append(tab);
write.append(appentStr4Length("失败原因",length));
write.append(enter);
write.append("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ");
write.append(enter);
CharHidden hidden = new CharHidden();
for(int i = 0;i<resultList.size();i++){
final PaymentBatchDetailDto p = resultList.get(i);
write.append(appentStr4Length(p.getId(),length)); //平台订单号
//write.append(tab);
write.append(appentStr4Length(p.getMchtBatchNo(),length));商户订单号
//write.append(tab);
write.append(appentStr4Length(p.getMchtBatchNo(),length));//商户批次号
//write.append(tab);
write.append(appentStr4Length(hidden.exec(new ArrayList<String>(){{add(p.getAccountNo());}}).toString(),30));//账号
//write.append(tab);
write.append(appentStr4Length(p.getAccountName(),length));//账户名称
//write.append(tab);
write.append(appentStr4Length(p.getAccountType(),length));//账户类型
//write.append(tab);
write.append(appentStr4Length(p.getAmount(),length));//金额
//write.append(tab);
write.append(appentStr4Length(p.getStatus(),length));//状态
//write.append(tab);
write.append(appentStr4Length(p.getFee(),length));//手续费
//write.append(tab);
write.append(appentStr4Length(p.getPaymentBusinessType(),length));//支付类型
//write.append(tab);
write.append(appentStr4Length(p.getCreatedDate(),length));//创建日期
//write.append(tab);
write.append(appentStr4Length(p.getResponseMsg(),length));//失败原因
write.append(enter);
}
buff.write(write.toString().getBytes("UTF-8"));
buff.flush();
buff.close();
} else {
throw new MemberServiceException(EMemberError.E0001.name(),
EMemberError.E0001.getValue());
}
} catch (Exception e) {
MessageBean messageBean = new MessageBean();
messageBean.setType(MessageBean.TYPE_EXCEPTION);
messageBean.setObject(0, MessageBean.EXCEPTION_LEVEL_ERROR);
messageBean.setObject(1, MchtDateUtil.formatCurrDateTime(MchtDateUtil.DF_Y_M_D_HMS));
messageBean.setObject(2, "ops-mcht-app");
messageBean.setObject(3, "支付批次明细");
messageBean.setObject(4, "com.smartpay.ops.mcht.view.agencyPay.AgencyPayController");
messageBean.setObject(5, "代付支付批次明细下载异常");
// end monitor
LoggerUtil.error(messageBean.toString());
LoggerUtil.error(e);
try {
buff.write(e.getMessage().getBytes());
} catch (IOException e1) {
e1.printStackTrace();
}
}finally{
try {
buff.close();
outStr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
再说两句
计算字符的时候,由于发现在txt文件中中文占的宽度是英文字符的两倍,所以统计的时候要把中文宽度值记为2,英文为1,最后计算出要补充的空格字符。