参考自:https://www.2cto.com/kf/201807/759940.html
https://www.xuebuyuan.com/zh-hant/3246500.html
https://blog.csdn.net/wurui8/article/details/43236207
UCanAccess官网:http://ucanaccess.sourceforge.net/site.html#examples
Java8 连接Access数据库UCanAccess的操作介绍
Java8 中JDK1.8中不再包含access桥接驱动,因此不再支持jdbcodbc桥接方式。
1.java Access JDBC jar包:Access_JDBC30.jar(正常是收费的)使用导入数据库相应的jar包,进行连接。
2.UCanAccess是一个Microsoft Access的开源JDBC驱动实现。
我用的是方法2。
首先pom引入
net.sf.ucanaccess
ucanaccess
4.0.4
首先新建一个空白的access文件名字随便取,我这边取名为blank.accdb(新版的sccess)/blank.mdb(旧版的)都能用。把文件放在resource文件夹下
新建一个工具类:
package io.renren.modules.recruitStudents.util;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* @program: security-enterprise
* @@return: $
* @description: 导出Access文件
* @author:
* @create: 2019-03-26 10:24
**/
public class AccessUtil {
private Connection connection;
private Statement statement;
private String softPath;
private String softAccessPath;
// 空白mdb文件路徑. 直接保存在src/cn/iwoo/dataexport/common/下.(这边读取不到,直接放在respurce下面,然后就能直接读取到,我水平还比较差还没研究出路径的问题)
private final String blankMdbFilePath = "io/renren/modules/recruitStudents/util/";
// 空白mdb文件名
private final String blankMdbFileName = "blank.accdb";//(新版的access是accdb结尾)
//private final String blankMdbFileName = "blank.mdb";
// 需要保存到的新的mdb文件路徑和名
private String savedMdbFilePathAndName = defaultSavedMdbFilePath + defaultSavedMdbFileName;
// 新mdb文件路徑
// public static final String defaultSavedMdbFilePath = "E:\\WorkSpaceIDEA\\SpringBoot_kfzs\\";//windows本机
public static final String defaultSavedMdbFilePath = "../file/";//linux服务器(不加..的话会生成在target文件夹下面)
// 新mdb文件名
public static final String defaultSavedMdbFileName = "studentInfo.mdb";
// mdb文件後綴
public static final String defaultSavedMdbFileExtension = ".mdb";
//标准的单例模式
private static AccessUtil instance = new AccessUtil();
private AccessUtil() {
}
public static AccessUtil getInstance() {
return instance;
}
/**
* Description: 设置新的文件路径和名称
*/
public void setSavedFilePathAndName(String newFilePathAndName) {
this.savedMdbFilePathAndName = newFilePathAndName;
}
/**
* Description:删除存在的mdb文件
*/
public void deleteOldMdbFile() throws Exception {
File oldTargetFile = new File(savedMdbFilePathAndName);
if (oldTargetFile.exists()) {
oldTargetFile.delete();
}
}
/**
* Description: 将空白mdb文件复制到指定目录
*/
public void copyBlankMdbFile() throws Exception {
// System.out.println(blankMdbFilePath + blankMdbFileName);
InputStream is = this.getClass().getClassLoader().getResourceAsStream("blank.mdb");
OutputStream out = new FileOutputStream(savedMdbFilePathAndName);
byte[] buffer = new byte[1024];
int numRead;
while ((numRead = is.read(buffer)) != -1) {
out.write(buffer, 0, numRead);
}
is.close();
out.close();
}
public void connetAccessDB(String path, String fileName) throws Exception {
String savedMdbFilePathAndName = path + fileName;
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); /* often not required for Java 6 and later (JDBC 4.x) */
String database = "jdbc:ucanaccess://"+savedMdbFilePathAndName.trim()+";memory=true";
connection = DriverManager.getConnection(database, "", "");
statement = connection.createStatement();
}
/**
* Description: 打开mdb文件的连接
*/
public Connection connetAccessDB() throws Exception {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); /* often not required for Java 6 and later (JDBC 4.x) */
String database = "jdbc:ucanaccess://"+savedMdbFilePathAndName.trim()+";memory=true";
connection=DriverManager.getConnection(database,"","");
statement = connection.createStatement();
return connection;
}
/**
* Description: 执行特定sql语句
*/
public void executeSql(String sql) throws Exception {
statement.execute(sql);
}
/**
* Description: 关闭连接
*/
public void closeConnection() throws Exception {
statement.close();
connection.close();
}
//测试用
public static void main(String[] args) {
AccessUtil au = AccessUtil.getInstance();
String sql = "create table Archives_tbl (LLR MEMO,LLRQ MEMO,QZH MEMO,MLH MEMO,AJH MEMO,DH MEMO,BGJH MEMO,FLJH MEMO,MJ MEMO,AJBT MEMO,ND MEMO,DW MEMO,JS MEMO,YC MEMO,BGQX MEMO,QSRQ MEMO,JZRQ MEMO,BZ MEMO);";
String sql1 = "create table Archives_tbl (QZH MEMO,MLH MEMO,AJH MEMO,DH MEMO,BGJH MEMO,FLJH MEMO,MJ MEMO,AJBT MEMO,ND MEMO,DW MEMO,JS MEMO,YS MEMO,BGQX MEMO,QSRQ MEMO,JZRQ MEMO,BZ MEMO);";
String sql2 = "create table Files_tb1 (SXH MEMO,WH MEMO,TM MEMO,ZRZ MEMO,ZTC MEMO,RQ MEMO,YC MEMO,YS MEMO,MJ MEMO,LDPSR MEMO,GB MEMO,QTZT MEMO,BZ MEMO,DH MEMO,Vpath MEMO);";
try {
au.copyBlankMdbFile();
au.connetAccessDB();
au.executeSql(sql1);
au.executeSql(sql2);
au.closeConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
public void setSoftPath(String softPath) {
this.softPath = softPath;
}
public void setSoftAccessPath(String softAccessPath) {
this.softAccessPath = softAccessPath;
}
//这个就是从服务器上下载文件
public String downloadFile(HttpServletResponse response){
String downloadFilePath = defaultSavedMdbFilePath;//被下载的文件在服务器中的路径,
String fileName = defaultSavedMdbFileName;//被下载文件的名称
File file = new File(downloadFilePath+fileName);
System.out.println(file.length());
if (file.exists()) {
// response.setContentType("application/octet-stream");// 设置强制下载不打开
// response.setHeader("Location",fileName);
// response.reset();
response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
response.setContentType("application/octet-stream; charset=UTF-8");
response.setHeader("Content_Length",file.length()+"");
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream outputStream = response.getOutputStream();
// IOUtils.write(buffer, outputStream);
int i = bis.read(buffer);
while (i != -1) {
outputStream.write(buffer, 0, i);
i = bis.read(buffer);
}
return "下载成功";
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
response.getOutputStream().flush();
response.getOutputStream().close();
fis.close();
bis.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
return "下载失败";
}
}
下面是调用的方法:
@GetMapping("exportAccess")
@ApiOperation("导出Access数据文件")
@LogOperation("导出Access数据文件")
@RequiresPermissions("recruitStudents:recruitsign:save")
public Result exportAccess(@ApiIgnore @RequestParam Map params,HttpServletResponse response){
System.out.println("导出Access数据文件");
PreparedStatement sql;
List list = recruitSignService.getList(params);
AccessUtil au = AccessUtil.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//这边也能直接执行sql语句
//含特殊符号的字段整个都要用[]括起来
// String sql1 = "create table Recruit_Student(编号 counter primary key,姓名 VarChar,性别 VarChar);";
try {
au.copyBlankMdbFile();
Connection connection = au.connetAccessDB();
sql = connection.prepareStatement("insert into Recruit_Student values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
for(int i=0;i();
}
后台代码到这完成了。我一直调用这个方法但是不成功,按照正常前台点击导出,就会下载文件了,但是我这边用的是element-ui前台的请求也是有讲究的才能正常下载文件请看前台方法代码:
// 导出access文件
exportAccess () {
var params = qs.stringify({
'token': Cookies.get('token'),
...this.dataForm
})
window.location.href = `${window.SITE_CONFIG['apiURL']}/recruitStudents/recruitsign/exportAccess?${params}`
//下面注释掉的能执行方法但是没办下载文件到本地
// this.$http['post'](`/recruitStudents/recruitsign/exportAccess`, this.dataForm).then(({ data: res })=> {
// if (res.code !== 0) {
// return this.$message.error(res.msg)
// }
// }).catch(() => { })
},
如果还不行也有可能是access问题引起的,请看https://blog.csdn.net/qq_37616870/article/details/79057075链接
在这边再次感谢以上链接的作者。