Dbf工具类
配置环境
<!--itxt--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;import com.enlistboot.common.exception.ServiceException;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;import com.enlistboot.common.annotation.Dbf;
import com.linuxense.javadbf.DBFDataType;
import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFReader;
import com.linuxense.javadbf.DBFWriter;public class DBFUtils<E> {private static final Logger log = LoggerFactory.getLogger(DBFUtils.class);static Map<String, Object> CONVERTER_EXP_MAP = new HashMap<>(16);public DBFUtils() {}/*** 导入DBF* * @param request* @param fileParamName* @throws ServletException* @throws IOException*/public static void importDBF(HttpServletRequest request, String fileParamName)throws ServletException, IOException {Part filePart = request.getPart(fileParamName);String fileName = getFileName(filePart);// 将文件保存到临时目录String tempPath = System.getProperty("java.io.tmpdir");String filePath = tempPath + File.separator + fileName;saveFile(filePart, filePath);// 导入DBF数据// importData(filePath);// 删除文件deleteTempFile(tempPath);}private static String getFileName(Part part) {String contentDisposition = part.getHeader("content-disposition");String[] parts = contentDisposition.split(";");for (String item : parts) {if (item.trim().startsWith("filename")) {return item.substring(item.indexOf('=') + 1).trim().replace("\"", "");}}return null;}private static void deleteTempFile(String filePath) {File file = new File(filePath);if (file.exists()) {file.delete();}}private static void saveFile(Part part, String filePath) throws IOException {try (InputStream inputStream = part.getInputStream();OutputStream outputStream = new FileOutputStream(filePath)) {byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}}}public List<E> importData(InputStream fis, Class<E> cls) throws IOException {
// Charset charset = Charset.forName("GBK");
// Charset charset = Charset.forName("UTF8");DBFReader reader = new DBFReader(fis, Charset.forName("GBK"));// 调用DBFReader对实例方法得到path文件中字段的个数int fieldsCount = reader.getFieldCount();// 判断是否包含指定的字段List<Field> classFields = Arrays.asList(cls.getDeclaredFields());// 取出字段信息for (int i = 0; i < fieldsCount; i++) {DBFField field = reader.getField(i);System.out.println(field.getName());boolean containsField = classFields.stream().anyMatch(f -> f.getName().equals(field.getName()));if(!containsField){throw new ServiceException("导入文件列名:"+field.getName()+"不存在");}}Object[] rowValues;// 一条条取出path文件中记录List<E> dataList = Lists.newArrayList();while ((rowValues = reader.nextRecord()) != null) {E e = null;try {e = (E) cls.newInstance();} catch (Exception e8) {}for (int i = 0; i < rowValues.length; i++) {DBFField field = reader.getField(i);Object object = rowValues[i];System.out.println(i + "-------" + object + "--------" + field.getName());String val = "";if (StringUtils.isNotNull(object)) {val = object.toString();}Reflections.invokeSetter(e, field.getName(), val);}dataList.add(e);}return dataList;}public static <T> void exportToDbf(HttpServletResponse response, Class<?> clazz, List<T> dataList,String fileName) {try {response.setContentType("application/x-dbf;");response.setCharacterEncoding("UTF-8");response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(fileName + ".dbf", "UTF-8"));// 获取字段数量和记录数量int numFields = getNumFields(clazz);int numRecords = dataList.size();// 读取内容转表达式中的值
// setFieldValue(dataList);// 创建一个包含字段信息的 DBFField 数组DBFField[] fields = getFields(clazz);// 创建一个 DBFWriter 对象,用于写入 DBF 文件
// DBFWriter writer = new DBFWriter(response.getOutputStream(), Charset.forName("GBK"));DBFWriter writer = new DBFWriter(response.getOutputStream(), Charset.forName("GBK"));writer.setFields(fields);if (!CollectionUtils.isEmpty(dataList)) {// 将每个 Person 对象的属性值写入到 DBF 文件中for (int i = 0; i < numRecords; i++) {Object[] record = new Object[numFields];T obj = dataList.get(i);for (int j = 0; j < numFields; j++) {record[j] = getFieldValue(obj, j);}writer.addRecord(record);}}// 关闭 DBFWriter 对象writer.close();} catch (Exception e) {
// log.error(e.getMessage());throw new RuntimeException(e.getMessage(), e);}}private static <T> int getNumFields(Class<?> clazz) {Field[] fields = clazz.getDeclaredFields();int count = 0;for (Field field : fields) {if (field.isAnnotationPresent(Dbf.class)) {count++;}}return count;}private static <T> DBFField[] getFields(Class<?> clazz) {Field[] fields = clazz.getDeclaredFields();int numFields = getNumFields(clazz);if (numFields < 0) {numFields = 0;}DBFField[] resultFields = new DBFField[numFields];int index = 0;boolean flag=false;for (Field field : fields) {if (field.isAnnotationPresent(Dbf.class)) {Dbf fieldNameAnnotation = field.getAnnotation(Dbf.class);int fieldIndex = fieldNameAnnotation.order();if (fieldIndex == 0) {flag=true;}if(flag){fieldIndex = index;}String fieldName = fieldNameAnnotation.name();if (fieldName.length() > 10) {fieldName = fieldName.substring(0, 10);}DBFDataType fieldType = DBFDataType.CHARACTER;if (field.getType() == int.class || field.getType() == Integer.class) {fieldType = DBFDataType.NUMERIC;} else if (field.getType() == double.class || field.getType() == Double.class) {fieldType = DBFDataType.FLOATING_POINT;}resultFields[fieldIndex] = new DBFField(fieldName, fieldType, 20); // 字段类型设置为CHARACTER,长度为10个字符index++;}}return resultFields;}public static <T> void setFieldValue(List<T> dataList) {try {for (T t : dataList) {if (!ObjectUtils.isEmpty(t)) {Field[] fields = t.getClass().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(Dbf.class)) {Dbf fieldNameAnnotation = field.getAnnotation(Dbf.class);String converterExp = fieldNameAnnotation.readConverterExp();if (StringUtils.isNotEmpty(converterExp)) {field.setAccessible(true);// 读取转换值if (!ObjectUtils.isEmpty(t)) {field.set(t, parseConverterExp(field.get(t), converterExp));}}}}}}} catch (IllegalAccessException e) {e.printStackTrace();}}private static Object parseConverterExp(Object o, String converterExp) {CONVERTER_EXP_MAP = Arrays.stream(converterExp.split(",")).map(s -> s.split("=")).filter(arr -> arr.length == 2).collect(Collectors.toMap(arr -> arr[0], arr -> arr[1]));return CONVERTER_EXP_MAP.get(o);}private static <T> Object getFieldValue(T obj, int index) {if (ObjectUtils.isEmpty(obj)) {return null;}Field[] fields = obj.getClass().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(Dbf.class)) {Dbf fieldNameAnnotation = field.getAnnotation(Dbf.class);int fieldIndex = fieldNameAnnotation.order();if (fieldIndex == index) {try {field.setAccessible(true);return field.get(obj);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}}}return null;}
}