Java导出DBF文件(附带工具类)

news2024/11/17 13:28:11

导出DBF文件

先看效果
在这里插入图片描述

JavaDBF

使用JavaDBF库

数据类型映射

写入支持的类型

类型XBase类型XBase 符号JavaDBF 中使用的 Java 类型
字符CharacterCjava.lang.String
数值NumericNjava.math.BigDecimal
浮点Floating PointFjava.math.BigDecimal
布尔LogicalLjava.lang.Boolean
时间DateDjava.util.Date

注:读取这里不总结,可以参考上面链接的官方文档

安装

这里只讲Maven操作

在 pom.xml 中使用此依赖项将 JavaDBF 添加到项目中

<dependency>
	<groupId>com.github.albfernandez</groupId>
	<artifactId>javadbf</artifactId>
	<version>1.14.0</version>
</dependency>

编写DBF文件

创建 .dbf(DBFWriter) 数据文件时,必须处理两个方面:
1、定义字段(DBFField)
2、填充数据(public void addRecord(Object[] values))

官网的例子:

import com.linuxense.javadbf.*;
import java.io.*;

public class JavaDBFWriterTest {

	public static void main(String args[]) throws IOException {
		// 1、DBFWriter 用于创建 .dbf 文件
		DBFWriter writer = new DBFWriter(new FileOutputStream(args[0]));

		// 2、定义字段
		// 创建三个 DBFField 类的对象
		DBFField[] fields = new DBFField[3];
		fields[0] = new DBFField();
		fields[0].setName("emp_code"); // 给字段一个名字
		fields[0].setType(DBFDataType.CHARACTER); // 设置它的类型
		fields[0].setLength(10); // 字段的长度

		fields[1] = new DBFField();
		fields[1].setName("emp_name");
		fields[1].setType(DBFDataType.CHARACTER);
		fields[1].setLength(20);

		fields[2] = new DBFField();
		fields[2].setName("salary");
		fields[2].setType(DBFDataType.NUMERIC);
		fields[2].setLength(12);
		fields[2].setDecimalCount(2);

		// 3、写入字段
		writer.setFields(fields);

		// 4、填充数据
		Object rowData[] = new Object[3];
		rowData[0] = "1000";
		rowData[1] = "John";
		rowData[2] = new Double(5000.00);
		writer.addRecord(rowData);

		rowData = new Object[3];
		rowData[0] = "1001";
		rowData[1] = "Lalit";
		rowData[2] = new Double(3400.00);
		writer.addRecord(rowData);

		rowData = new Object[3];
		rowData[0] = "1002";
		rowData[1] = "Rohit";
		rowData[2] = new Double(7350.00);
		writer.addRecord(rowData);

		writer.close();
	}
}

到此,.dbf文件就创建成功。此时,还有个问题存在当出现中文字符时,内容显示?。

在这里插入图片描述

我们只需要做一下变动

DBFWriter writer = new DBFWriter(new FileOutputStream(args[0]), Charset.forName("GBK"));
// 或
DBFWriter writer = new DBFWriter(new FileOutputStream(args[0]), Charset.forName("UTF-8"));

工具类

1、创建 Dbf 注解类

import com.linuxense.javadbf.DBFDataType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义导出DBF数据注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Dbf
{
    /**
     * 列名字.   xxx,C,30  xxx位置的名字
     */
    public String name() default "";

    /**
     * 值类型 默认字符串  参考 DBFDataType 枚举类
     */
    public DBFDataType dataType() default DBFDataType.CHARACTER;

    /**
     * 数据长度
     *
     * 字符串   最大254
     * 布尔值   最大1
     * 时间     最大8
     * 数值     最大32
     *
     */
    public int length() default 1;

    /**
     * 精度
     */
    public int decimalCount() default 0;

    /**
     * 列显示的顺序
     */
    public int sort() default Integer.MAX_VALUE;
}

2、创建 DBFUtils 工具类

import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFWriter;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * DBF文件工具类
 **/
public class DBFUtils<T> {
    private DBFWriter writer;

    // 需要排除列
    private String[] excludeFields;

    // 注解字段信息
    private List<Object[]> fields;

    // 数据
    private List<T> data;

    // 实体
    private Class<T> clazz;

    public DBFUtils(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 排除列导出
     *
     * @param fields 列属性名 示例[单个"name"/多个"id","name"]
     * @throws Exception
     */
    public void excludeColumn(String... fields)
    {
        this.excludeFields = fields;
    }

    /**
     * 导出DBF
     *
     * <h1>写入DBF支持的数据类型</h1>
     *
     * XBase类型	        XBase符号	   JavaDBF中使用的Java类型
     * Character	    C	           java.lang.String
     * Numeric	        N	           java.math.BigDecimal
     * Floating Point	F	           java.math.BigDecimal
     * Logical	        L	           java.lang.Boolean
     * Date	            D	           java.util.Date
     *
     * @param response 返回数据
     * @param data 导出数据集合
     * @param fileName 文件名称
     */
    public void exportDBF(HttpServletResponse response, List<T> data, String fileName)
    {
        try {
            // 初始化
            this.init(response, data, fileName);
            // 写入内容
            this.writeContent();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void init(HttpServletResponse response, List<T> data, String fileName) throws IOException {
        this.responseByDBF(response, fileName);
        this.writer = new DBFWriter(response.getOutputStream(), Charset.forName("GBK"));
        this.data = data;
        this.fields = this.getFields();
    }

    private void responseByDBF(HttpServletResponse response, String fileName) {
        response.setContentType("application/octet-stream; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".DBF");
    }

    /**
     * 往工作区中写入内容
     */
    private void writeContent() throws IllegalAccessException {
        int size = fields.size();

        // 写入表头
        writer.setFields(this.dbfFields());

        if (ObjectUtils.isNotEmpty(this.data)) {
            Object[] row = null;

            for (T vo : this.data) {
                row = new Object[size];

                for (int i = 0; i < size; i++) {
                    Object[] os = fields.get(i);

                    Field field = (Field) os[0];
                    field.setAccessible(true);
                    Object o = field.get(vo);
                    // TODO 这里可能会出现类型异常,遇到再处理
                    row[i] = o;
                }
                // 写入行数据
                writer.addRecord(row);
            }
        }

        writer.close();
    }

    /**
     * 获取表头
     *
     * @return  返回标题信息
     */
    private DBFField[] dbfFields() {
        int size = this.fields.size();

        // 写入表头
        DBFField[] dbfFields = new DBFField[size];
        for (int i = 0; i < fields.size(); i++) {
            Object[] os = fields.get(i);

            Dbf dbf = (Dbf) os[1];
            dbfFields[i] = new DBFField(dbf.name(), dbf.dataType(), dbf.length(), dbf.decimalCount());
        }

        return dbfFields;
    }

    /**
     * 获取导出DBF的字段
     *
     * @return  注解字段信息
     */
    private List<Object[]> getFields() {
        List<Object[]> fields = new ArrayList<Object[]>();
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        for (Field field : tempFields)
        {
            if (!ArrayUtils.contains(this.excludeFields, field.getName()))
            {
                // 单注解
                if (field.isAnnotationPresent(Dbf.class))
                {
                    Dbf attr = field.getAnnotation(Dbf.class);
                    if (attr != null)
                    {
                        field.setAccessible(true);
                        fields.add(new Object[] { field, attr });
                    }
                }
            }
        }
        return fields.stream().sorted(Comparator.comparing(objects -> ((Dbf) objects[1]).sort())).collect(Collectors.toList());
    }
}

3、使用
创建实体

import com.linuxense.javadbf.DBFDataType;

import java.math.BigDecimal;
import java.util.Date;

public class Student
{
    private static final long serialVersionUID = 1L;

    // 名称
    @Dbf(name = "NAME", length = 254)
    private String name;

    //  年龄
    @Dbf(name = "AGE", dataType = DBFDataType.NUMERIC, length = 32)
    private Integer age;

    // 成绩
    @Dbf(name = "GRADE", dataType = DBFDataType.NUMERIC, length = 32)
    private BigDecimal grade;

    // 是否寄宿
    @Dbf(name = "IS_LODGE", dataType = DBFDataType.LOGICAL, length = 1)
    private Boolean isLodge;

    // 入学时间
    @Dbf(name = "ENROL_TIME", dataType = DBFDataType.DATE, length = 8)
    private Date enrolTime;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public BigDecimal getGrade() {
        return grade;
    }

    public void setGrade(BigDecimal grade) {
        this.grade = grade;
    }

    public Boolean getIsLodge() {
        return isLodge;
    }

    public void setIsLodge(Boolean islodge) {
        this.isLodge = islodge;
    }

    public Date getEnrolTime() {
        return enrolTime;
    }

    public void setEnrolTime(Date enrolTime) {
        this.enrolTime = enrolTime;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", grade=" + grade +
                ", isLodge=" + isLodge +
                ", enrolTime=" + enrolTime +
                '}';
    }
}

Controller

@PostMapping("/exportDBF")
public void exportDBF(HttpServletResponse response)
{
    List<Student> data = new ArrayList<>();

    Student bean = new Student();
    bean.setName("小明");
    bean.setAge(16);
    bean.setGrade(BigDecimal.valueOf(80));
    bean.setIsLodge(Boolean.FALSE);
    bean.setEnrolTime(new Date(2023, 8, 8));
    data.add(bean);
    bean = new Student();
    bean.setName("小刚");
    bean.setAge(16);
    bean.setGrade(BigDecimal.valueOf(85));
    bean.setIsLodge(Boolean.FALSE);
    bean.setEnrolTime(new Date(2023, 8, 8));
    data.add(bean);
    bean = new Student();
    bean.setName("小华");
    bean.setAge(16);
    bean.setGrade(BigDecimal.valueOf(100));
    bean.setIsLodge(Boolean.TRUE);
    bean.setEnrolTime(new Date(2021, 8, 8));
    data.add(bean);
    bean = new Student();
    bean.setName("小丽");
    bean.setAge(16);
    bean.setGrade(BigDecimal.valueOf(90));
    bean.setIsLodge(Boolean.TRUE);
    bean.setEnrolTime(new Date(2022, 8, 8));
    data.add(bean);

    DBFUtils<Student> utils = new DBFUtils<>(Student.class);
    utils.exportDBF(response, data, null);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2066486.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

公司如何监控员工电脑,怎么监控电脑进程

在现代企业管理中&#xff0c;监控员工电脑的行为已成为确保工作效率、数据安全和合规性的重要措施。通过合理的监控手段&#xff0c;企业可以预防潜在的安全威胁&#xff0c;优化工作流程&#xff0c;并确保员工遵循公司的政策和规定。 公司监控员工电脑的常见方法 屏幕监控&…

什么是pk答题软件源码

答题软件的源码是开发答题软件的基础程序代码。由于答题软件的功能和复杂程度不同&#xff0c;其源码也会有很大差异。 一般来说&#xff0c;答题软件的源码可能包含以下几个主要部分&#xff1a; 一、用户界面部分 登录和注册界面&#xff1a; 允许用户输入用户名、密码等信…

C++资料电子书资源PDF免费分享

C电子书 这里写目录标题 C电子书目录资源获取 目录 《数据结构(C语言版)》(严蔚敏 吴伟明编著).pdf 7.6MB 《C程序设计题解与上机指导》(第二版).谭浩强.pdf 7.0MB 《C程序设计(第四版)学习辅导》.谭浩强.扫描版.pdf 13.1MB 《C程序设计》第一版&#xff08;谭浩强&#xff09…

个人笔记--python画图(一维,二维,三维)

1. 一维 1. plot import numpy as np import matplotlib.pyplot as plt# linspace(): 创建等间距的数值序列 x np.linspace(0, 2 * np.pi, 100)u np.sin(x)# 绘制一维图形 plt.figure() plt.plot(x, u) plt.title(Plot of sin(x)) plt.xlabel(x) plt.ylabel(sin(x)) plt.sh…

监控摄像头能看到电脑屏幕吗?公司监控摄像头拍员工电脑屏幕!

监控摄像头已经成为许多企业和公共场所不可或缺的安全管理工具。 它们不仅守护着物理空间的安全&#xff0c;也在一定程度上影响着企业的运营管理和员工的行为规范。 然而&#xff0c;当“公司监控摄像头拍员工电脑屏幕”这一话题被提出时&#xff0c;不禁引发了广泛的讨论与…

Sketch for mac(专业矢量绘图设计软件100.3版) 中文激活版 一键快速安装!

Sketch 是一款专为 macOS 设计的专业矢量图形编辑软件&#xff0c;自发布以来便成为 UI/UX 设计师首选的工具之一。其简洁高效的用户界面、强大的设计功能&#xff0c;以及与 macOS 系统的深度集成&#xff0c;使得 Sketch 在设计领域享有很高的声誉。无论是移动应用设计、网页…

PT:如何获取net的Delta delay信息

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 来自星球提问: crosstalk的Delta delay可以从三个渠道获取: report_timing

监控用户登录信息,执行事务码情况

CMOD->SUSR0001 *&---------------------------------------------------------------------* *& 包含 ZXUSRU01 *&---------------------------------------------------------------------*DATA:lv_sblm_obj TYPE sblm_obj.CALL FUNCTION ZFMB…

2-Git远程仓库

Git中存在两种类型的仓库&#xff0c;即本地仓库和远程仓库。那么我们如何搭建Git远程仓库呢&#xff1f;我们可以借助互联网上提供的一些代码托管服务来实现&#xff0c;其中比较常用的有GitHub、码云、GitLab等。 一、配置远程仓库 1.注册登录Gitee/Github GitHub 地址&am…

【ComfyUI Flux_dev_gguf】 AI绘画提示词,轻松实现AI仰角摄影技巧。秒出AI大片~

前言 **hello&#xff0c;大家好&#xff0c;我是老徐&#xff0c;热爱AI&#xff0c;一路同行&#xff0c;与你相伴~喜欢的可以关注老徐&#xff0c;**在文章底部添加老徐微信&#xff0c;加入老徐AI绘画交流群 今天老徐简单和大家分享下基于ComfyUI Flux_dev_gguf 工作流&…

CX1020 N010处理器CX1020-N010模块面价

CX1020 N010处理器CX1020-N010模块面价 CX1020 N010处理器CX1020-N010模块面价 CX1020 N010处理器CX1020-N010模块面价 CX1020-N010处理器CX1020 N010模块引脚线 CX1020-N010处理器CX1020 N010模块接线图 CX1020-N010处理器CX1020 N010模块电路图 CX1020-N010中央处理器&…

R 2火灾温度预测

火灾温度预测 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 使用LSTM进行时间序列预测 这周学习如何使用长短期记忆网络&#xff08;LSTM&#xff09;进行时间序列预测。使用PyTorch框架来构建和训练模型&…

【大数据算法】一文掌握大数据算法之:时间亚线性算法。

时间亚线性算算法 1、引言2、时间亚线性算法2.1 定义2.2 分类2.3 核心原理2.4 算法公式2.5 代码示例 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;大数据算法知识难不难啊&#xff1f; 小鱼&#xff1a;你在职场打拼这么多年&#xff0c;竟然还能问出来这个问题。 小屌…

婚恋交友系统该如何制作成品系统?

制作婚恋交友系统的成品系统是一个综合性的过程&#xff0c;涉及多个关键步骤和技术要点。以下是一个详细的制作流程&#xff1a; 1. 需求分析 市场调研&#xff1a;首先需要对婚恋交友市场进行深入调研&#xff0c;了解目标用户群体的需求、喜好、习惯以及市场痛点。用户画像…

C学习(数据结构)--> 实现顺序结构二叉树

目录 一、堆的概念与结构 性质 二叉树的性质 二、堆的实现 1、结构 2、初始化与销毁 3、入堆与出堆&#xff08;小堆&#xff09; 1&#xff09;Swap 2&#xff09;入堆 1 数据的向上调整 2 入堆 3&#xff09;出堆 1 数据的向下调整 2 出堆 三、其他 1、入堆与出…

解决Github无法连接codespace情况

使用这个DNS即可 CN - 中国互联网络信息中心CNNIC SDNS1.2.4.8,,True 参见&#xff1a; GitHub 无法访问解决办法 - 哔哩哔哩

一些可以参考的文档集合17

应用运行主目录 之前的文章集合: 一些可以参考文章集合1_xuejianxinokok的博客-CSDN博客 一些可以参考文章集合2_xuejianxinokok的博客-CSDN博客 一些可以参考的文档集合3_xuejianxinokok的博客-CSDN博客 一些可以参考的文档集合4_xuejianxinokok的博客-CSDN博客 一些可以…

乱弹篇(42)处暑与吃秋

“太热了。8点收竿&#xff0c;匆忙回家降温。”刚才完笔者把这话发给了微信亲友。 书画家黄老弟回复&#xff1a;“又是保长吧&#xff1f;天热了&#xff0c;鱼不出来。下次努力。” 知友家乡兰回复&#xff1a;“是啊&#xff0c;自贡已达40度&#xff01;” 在“电老虎”…

为什么录屏没有声音?教你三招,解决系统与麦克风声音录制技巧

电脑录屏声音同步技巧&#xff1a;系统与麦克风声音录制 在游戏录制和微课制作中&#xff0c;音画同步是保证观众体验的关键因素。无论是紧张刺激的游戏解说&#xff0c;还是知识传递的微课讲解&#xff0c;清晰同步的声音都能让内容更加生动&#xff0c;更能吸引观众的注意力…

【UE5.1】NPC人工智能——06 NPC攻击

目录 前言 效果 步骤 一、准备NPC狮子攻击的动画 二、NPC狮子攻击玩家造成伤害 前言 在上一篇中&#xff08;【UE5.1】NPC人工智能——05 给NPC添加视觉感知&#xff09;我们已经给NPC添加了感知功能&#xff0c;使其在感知到玩家后就跑向玩家。本篇要实现的功能是&#x…