Excel文件一键上传并解析完成数据批量导入数据库

原来做文件上传的时候,都是有一个输入框,点击上传按钮,先浏览文件,选择文件后,把文件的路径保存到form表单中,最后通过form表单提交到服务端。这样的界面不是很美观。为了用户有更好地体验(UE),现在的大多数系统都是采用一键文件上传,用户点击上传按钮,选择要上传的文件,确定之后,文件就直接上传了,不需要提供额外的form表单,而且可以实现页面文件上传无刷新。

文件上传和一键文件上传的原理

文件上传需要具备的条件:

客户端:
1、 Form 表单编码方式 multipart/form-data
2、 提交方式必须为 post
3、 上传文件对应 input type=”file” 元素要提供 name 属性

服务端:

使用Struts2进行文件上传

struts2-default.xml 配置

在这里插入图片描述

FileUploadInterceptor拦截器已经被配置 defaultStack 中,这个拦截器对Apache commons-fileupload文件上传工具包进行了封装,使用更便捷。

客户端–使用jQuery ocupload插件实现一键上传

Ocupload即One-click upload,一键上传。

一键上传原理

在这里插入图片描述

插件下载的官网现在不能正常访问,插件在文章末提供的示例项目中。示例项目仅供大家参考!

首先在项目中导入这个插件,并在页面中进行引用。

注:由于这个插件是jQuery的插件,所在需要在引入这个插件之前,先在页面中引入jQuery文件。

插件的使用

官方示例:

$(element).upload({ 
        name: 'file',  //<input type='file' name='file'/> 插件的默认值是file
        action: '',   //请求服务器的路径
        enctype: 'multipart/form-data',  //mime类型 ,插件默认的即可
        params: {},   //请求额外传递的参数,一般不用设置
        autoSubmit: true,   //是否在选择文件后自动提交form表单
        onSubmit: function() {},  //在提交form表单之前进行的操作
        onComplete: function() {},  //完成文件上传后,进行的操作
        onSelect: function() {}   //选择文件后,进行的操作
}); 

代码演示:

//为按钮绑定一键上传插件
	$("#ocupload").upload({ 
        action: '../ocupload_batchImport.action',   //请求服务端的路径
        //完成上传后,触发的事件,response参数是响应到页面的json字符串
        onComplete: function(response) {
        	//将返回的json字符串response转换成json对象
        	var data = JSON.parse(response);
        	if(data.result){
        		alert("文件上传成功!");
        	}else{
        		alert("文件上传失败!");
        	}
        },
        //选择文件后,触发的事件
        onSelect: function() {
        	this.autoSubmit = false;    //这个是一键上传插件中的属性
        	//定义一个正则表达式,用来限定只能上传以.xls或以.xlsx结尾的Excel文件
        	var regex = /^.*\.(xls|xlsx)$/ ;
        	
        	//获得上传文件的名字
        	var filename = this.filename();    //这个方法是由一键上传的插件提供
        	if(regex.test(filename)){
        		//符合条件,提交form表单
        		this.submit();            //这个方法是由一键上传的插件提供
        	}else{
        		//不符合条件,给出提示
        		alert("只能上传以.xls或以.xlsx结尾的文件!");
        	}
        }

服务端–使用Apache POI解析Excel数据

编写 OcuploadAction类 接收上传文件

由于Struts2的FileUploadInterceptor拦截器对文件上传工具包进行了封装,我们只需要按照这个拦截器中定义的规范,即可完成文件的上传。

在 Action 定义三个成员变量
private File [页面元素 name]
private String [页面元素 name]ContentType;
private String [页面元素 name]FileName;

并在Action中提供set方法

Apache POI

POI的功能可以解析微软的Office组件的文档格式。
企业中通常使用其解析Excel文档或生成Excel文档(SS)。
POI支持HSSF解析(.xls–Excel97-2007之前版本,仅支持65535行记录)和XSSF解析(.xlsx–Excel2007及以后版本)。

1,在项目中引入POI的坐标(根据需要可以引入HSSF和XSSF的)

<poi.version>3.12</poi.version>
<!-- 解析HSSF的包  就是解析Excel 97-2007格式的Excel文档(以.xls结尾的)-->
  	<dependency>
  		<groupId>org.apache.poi</groupId>
  		<artifactId>poi</artifactId>
  		<version>${poi.version}</version>
  	</dependency>
  	<!-- 解析XSSF的包  解析Excel 2007格式的Excel文档(以.xlsx结尾的) 这个包依赖poi包-->
  	<dependency>
  		<groupId>org.apache.poi</groupId>
  		<artifactId>poi-ooxml</artifactId>
  		<version>${poi.version}</version>
  	</dependency>
  	<dependency>
  		<groupId>org.apache.poi</groupId>
  		<artifactId>poi-ooxml-schemas</artifactId>
  		<version>${poi.version}</version>
  	</dependency>

2.解析Excel工作簿

POI解析的基本过程:打开WorkBook工作簿文件—》找到Sheet工作表—》遍历读取Rows行—》读取行中的cell单元格。

@ParentPackage("json-default")
@Namespace("/")
@Controller
@Scope("prototype")
public class OcuploadAction extends BaseAction {

	// 属性驱动,获取客户端请求过来的file文件
	private File file; // 属性名对应客户端form表单中设置的name属性的值

	private String fileContentType; // 上传文件的类型

	private String fileFileName; // 上传文件的名称

	public void setFile(File file) {
		this.file = file;
	}

	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	private String JSON = "json";

	@Autowired
	private OcuploadService ocuploadService;

	@Action(value = "ocupload_batchImport", results = { @Result(name = "json", type = "json") })
	public String batchImport() {

		// 定义一个存放返回结果集的map
		Map<String, Object> resultMap = new HashMap<>();

		// 定义一个list集合,用户存放实体对象
		List<Area> list = new ArrayList<>();

		FileInputStream inputStream = null;

		Workbook book = null;
		try {
			// Excel文件解析

			// 1.创建文件输入流对象,读取文件
			inputStream = new FileInputStream(file);

			// 2.创建Excel工作簿文件(包括.xls和.xlsx格式)
			book = WorkbookFactory.create(inputStream);

			// 3.打开需要进行解析的工作表sheet
			Sheet sheet = book.getSheetAt(0);

			// 4.遍历工作表对象sheet,获取到工作表中的每一行数据,对应一个实体对象(Area)
			for (Row row : sheet) {
				// 跳过第一行比表头数据
				if (row.getRowNum() == 0) {
					continue;
				}

				// 一般来说,每一行的第一列都是标识列,如果第一列的单元格没有数据,则认为这一行数据无效,跳过
				if (StringUtils.isNotBlank(row.getCell(0).getStringCellValue())) {
					// 设置Area实体的部分属性
					Area area = setEntity(row);

					// ============================================================

					// 使用PinYin4j把字符串转成拼音

					// 去掉省份,城市,区域最后一个字(省,市,区)

					// 省份
					String province = area.getProvince().substring(0, area.getProvince().length() - 1);

					// 城市
					String city = area.getCity().substring(0, area.getCity().length() - 1);

					// 区域
					String district = area.getDistrict().substring(0, area.getDistrict().length() - 1);

					hanziTopinyin(area, province, city, district);

					// 把对象添加到list集合中
					list.add(area);
				}
			}

			// 5.调用业务层,批量导入数据
			ocuploadService.batchImport(list);
			// 解析成功
			resultMap.put("result", true);
		} catch (Exception e) {
			System.out.println(e.getMessage());
			// 解析失败
			resultMap.put("result", false);

		} finally {
			try {
				// 关闭资源
				book.close();
				inputStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		// 把map集合压入值栈,struts-json-plugin插件包,会把map自动转换成json数据
		pushToValueStack(resultMap);
		// 返回json数据
		return JSON;

	}

	// 把汉字转换成拼音
	public void hanziTopinyin(Area area, String province, String city, String district) {
		// 得到区域简码 例如:北京市北京市海淀区 简码:BJBJHD

		String[] headStr = PinYin4jUtils.getHeadByString(province + city + district);

		// 进行字符串拼接
		StringBuffer buffer = new StringBuffer();

		for (String str : headStr) {
			buffer.append(str);
		}

		// 把buffer转换成string,得到区域简码
		String shortcode = buffer.toString();

		// 设置区域简码
		area.setShortcode(shortcode);

		// 设置城市编码
		area.setCitycode(PinYin4jUtils.hanziToPinyin(city, ""));
	}

	/**
	 * @param row
	 * @return
	 */
	public Area setEntity(Row row) {
		// 创建一个Area对象,把数据存放到这个对象中,
		Area area = new Area();
		// 设置数据时,要对应上传文件的Excel表格中的列进行设置
		// 设置区域编号
		area.setId(row.getCell(0).getStringCellValue());
		// 设置省份
		area.setProvince(row.getCell(1).getStringCellValue());
		// 设置城市
		area.setCity(row.getCell(2).getStringCellValue());
		// 设置区域
		area.setDistrict(row.getCell(3).getStringCellValue());
		// 设置邮编
		area.setPostcode(row.getCell(4).getStringCellValue());
		return area;
	}

}

业务操作,添加数据到数据库就不在这里叙述,完整源码在文章末的示例项目中!

在上述代码中,还有关于PinYin4j的用法,下面做简单的介绍

Pinyin4j是一个流行的Java库,支持中文字符和拼音之间的转换,拼音输出格式可以定制。

Pinyin4j的使用

在项目中导入Pinyin4j的坐标

<pinyin4j.version>2.5.0</pinyin4j.version>
<!-- 支持字符串转换拼音 -->
  	<dependency>
  		<groupId>pinyin4j</groupId>
  		<artifactId>pinyin4j</artifactId>
  		<version>${pinyin4j.version}</version>
  	</dependency>

在示例项目里,提供了一个Pinyin4jUtils工具类,它对Pinyin4j的一些操作进行了封装。

支持的方法:

1.获得每个汉字拼音首字母
2.把汉字转成拼音,去掉每个字拼音之间的空格

例如:北京市
获得每个汉字拼音首字母 [B, J, S]
把汉字转成拼音,去掉每个字拼音之间的空格 beijingshi

public static void main(String[] args) {
		// pin4j 简码 和 城市编码 
		String s1 = "北京市"; 
		String[] headArray = getHeadByString(s1); // 获得每个汉字拼音首字母
		System.out.println(Arrays.toString(headArray));
		
		String s2 = hanziToPinyin(s1,"");  //把汉字转成拼音,去掉每个字拼音之间的空格
		System.out.println(s2);
	}

最后分享示例项目在GitHub上的地址:https://github.com/xiaoguige/ocupload

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DataGear是一款数据可视化分析平台,使用Java语言开发,采用浏览器/服务器架构,支持SQL、CSV、Excel、HTTP接口、JSON等多种数据源,主要功能包括数据管理、SQL工作台、数据导入/导出、数据集管理、图表管理、看板管理等。 系统特点: 1、可管理数据库驱动 可通过驱动程序管理功能添加数据库驱动程序,无需重启,即可支持连接新数据库; 2、多种格式的数据集 支持SQL、CSV、Excel、HTTP接口、JSON等多种格式的数据集; 3、多数据集聚合图表 一个图表可添加多个不同格式的数据集,将它们聚合展示; 4、插件式图表类型 每一种类型的图表都以图表插件形式提供,并内置了大量图表插件,管理员也可上传自定义图表插件,丰富系统图表类型; 5、可自由编辑的HTML看板模板 看板使用原生的HTML网页作为模板,可自由编辑、绑定、异步加载图表,并支持将任意HTML网页导入为看板; 6、丰富的看板API 看板页面内置了大量的页面端API,可用于个性化扩展看板功能。 模块介绍: 1、datagear-analysis 数据分析底层模块,定义数据集、图表、看板API 2、datagear-connection 数据库连接支持模块,定义可从指定目录加载JDBC驱动、新建连接的API 3、datagear-dataexchange 数据导入/导出底层模块,定义导入/导出指定数据数据的API 4、datagear-management 系统业务服务模块,定义数据源、数据分析等功能的服务层API 5、datagear-meta 数据源元信息底层模块,定义解析指定数据源表结构的API 6、datagear-persistence 数据数据管理底层模块,定义读取、编辑、查询数据源表数据的API 7、datagear-util 系统常用工具集模块 8、datagear-web 系统业务web模块,定义web控制器、操作页面 9、datagear-webapp 系统Web应用程序组织模块,定义将系统构建为标准WAR程序包的结构 10、datagear-webappembd 系统独立应用程序组织模块,定义将系统构建为独立可执行程序的结构 依赖: Java 8+ Servlet 3.0+ 编译: (执行单元测试编译,需要预先配置单元测试环境) mvn clean package (不执行单元测试编译,无需预先配置单元测试环境) mvn clean package -DskipTests 运行: cd datagear-webappembd/target/datagear-[version] (Linux环境) ./startup.sh (windows环境) startup.bat 调试: 1、将datagear以maven工程导入至IDE工具; 2、将datagear-webapp作为Web应用添加至servlet容器(比如Tomcat); 3、以调试模式运行Servlet容器。 调试注意: 在调试开发分支前(dev-*),建议先备份DataGear工作目录([用户主目录]/.datagear), 因为开发分支程序启动时会修改DataGear工作目录,可能会导致先前使用的正式版程序、以及后续发布的正式版程序无法正常启动。 调试时,系统仅会在第一次启动时升级内置数据库(Derby),如果遇到内置数据库访问异常,需要查看 datagear-management/src/main/resources/org/datagear/management/ddl/datagear.sql 文件,从中查找需要更新的SQL语句,手动更新至内置数据库。 系统自带了一个可用于为内置数据库执行SQL语句的简单工具类org.datagear.web.util.DerbySqlClient,可以在IDE中直接运行。注意:运行前需要先停止DataGear程序。 DataGear数据可视化分析平台 更新日志: v2.9.0 重构内置表格图表配置项,支持细粒度配置表格样式
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值