序文
プロジェクト開発中に、ファイルのアップロードおよびダウンロード機能が使用されることがあります。プロジェクトは、ユーザーがダウンロードできるテンプレートを提供します。ユーザーがダウンロードした後、必要なデータ コンテンツを追加してプロジェクトにアップロードします。プロジェクトのバックエンドはファイルを受信して解析します。データベースに保存する必要がある場合は、ファイルが保存されます。データベース関連の操作を実行します。では、ファイルのアップロードおよびダウンロード機能を実装するにはどうすればよいでしょうか? 以下のケースは参考用です (このプロジェクトは springboot に基づいており、フレームワークはEveryone アクセス許可フレームワークを使用し、フロントエンドとバックエンドの対話には ajax 通信を使用します)。
1.テンプレートファイルをダウンロードする
1. フロントエンドでテンプレートファイルのダウンロードリンクを作成します。
<a href="http://localhost:8080/admin/admin/equipment/download/" style="float: right" @click="tip">模板文件下载</a>
//此方法是点击模板文件下载,弹出注意事项。
<script>
var vm = new Vue({
el:'#rrapp',
data:{
},
methods: {
tip: function(){
layer.open({
type: 0,
offset: 'rt',
title: '注意事项'
,content: '设备名称不得为空;经费来源选填(行政、教学、其它)中的一个,分类号和归属单位查看sheet表2;其余可为空。'
});
}
}
});
</script>
2. バックエンドインターフェースの書き込み
プロジェクトの依存関係を追加する
<!-- POI support -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<!-- support xlsx,docx.. -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!-- /POI support -->
@RestController
@RequestMapping("admin/equipment")
public class EquipmentController {
/**
* 模板文件下载
* @param response
*/
@SysLog("模板文件下载")
@RequestMapping("/download")
public void download(HttpServletResponse response) {
try {
//获取文件模板
InputStream fis = Thread.currentThread().getContextClassLoader().getResourceAsStream("设备仪器用表.xls");
HSSFWorkbook workbook = new HSSFWorkbook(fis);
//设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("application/binary;charset=ISO8859-1");
//转码,免得文件名中文乱码
String fileName = java.net.URLEncoder.encode("设备仪器用表", "UTF-8");
//设置文件下载头
response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xls");
ServletOutputStream out = null;
out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭文件输出流
}
return;
}
}
3. バックエンドインターフェイス内のファイルテンプレートの場所
注: このテンプレート ファイルの場所は、テンプレートと同じレベルのリソース フォルダーの下にあります。
2. ファイルをアップロードし、データをデータベースにインポートします
1. フロントエンドにファイルアップロードボタンを作成します
<a class="btn btn-primary" id="upload"><i class="fa fa-plus"></i> 批量导入</a>
<script>
new AjaxUpload('#upload', {
action: baseURL + "admin/equipment/upload",
name: 'file',
autoSubmit:true,
responseType:"json",
// 告诉jQuery不要去处理发送的数据
processData : false,
// 告诉jQuery不要去设置Content-Type请求头
contentType : false,
onSubmit:function(file, extension){
if (!(extension && /^(xlsx|xls)$/.test(extension.toLowerCase()))){
alert('只支持xlsx、xls格式的Excel文件!');
return false;
}
},
onComplete : function(file, r){
if(r.code == 0){
alert(r.url);
vm.reload();
}else{
alert(r.msg);
}
}
});
</script>
2. エンティティクラス
package io.renren.modules.admin.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.renren.common.validator.group.AddGroup;
import io.renren.common.validator.group.UpdateGroup;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
/**
* 设备表
*
* @author yzs
* @email [email protected]
* @date 2020-11-19 15:26:13
*/
@Data
@TableName("equipment")
public class EquipmentEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId
private Long id;
/**
* 设备编号
*/
private String number;
/**
* 分类号
*/
private String classnum;
/**
* 分类名
*/
@TableField(exist = false)
@NotBlank(message="分类名不能为空", groups = {
AddGroup.class, UpdateGroup.class})
private String classname;
/**
* 设备名称
*/
private String name;
/**
* 型号
*/
private String model;
/**
* 规格
*/
private String specification;
/**
* 单价
*/
private Double price;
/**
* 厂商
*/
private String vendor;
/**
* 出厂号
*/
private String factorynum;
/**
* 购置日期
*/
private Date time;
/**
* 经费来源
*/
private String funding;
/**
* 归属单位编号
*/
private String deptnum;
/**
* 归属单位名称
*/
@TableField(exist = false)
private String deptname;
/**
* 状态(0未分配 1已分配 2已报废)
*/
private Integer status;
}
3. バックエンドインターフェースの書き込み
@RestController
@RequestMapping("admin/equipment")
public class EquipmentController {
@Autowired
private EquipmentService equipmentService;
/**
* 上传文件
*/
@SysLog("上传文件")
@RequestMapping("/upload")
public R upload(@RequestParam("file") MultipartFile file) throws Exception {
if (file.isEmpty()) {
throw new RRException("上传文件不能为空");
}
FileInputStream inputStream = (FileInputStream) file.getInputStream();
//用于存储解析后的Excel文件
Workbook workbook = new HSSFWorkbook(inputStream);
//得到表
Sheet sheet = workbook.getSheetAt(0);
//获取标题内容
// Row rowTitle = sheet.getRow(1);
// if (rowTitle != null){
// int cellCount = rowTitle.getPhysicalNumberOfCells();
// for (int cellNum=0; cellNum<cellCount; cellNum++){
// Cell cell = rowTitle.getCell(cellNum);
// if (cell != null){
// int cellType = cell.getCellType();
// String cellValue = cell.getStringCellValue();
// }
// }
// }
//获取内容信息
int rowCount = sheet.getPhysicalNumberOfRows();
for (int rowNum=1; rowNum<rowCount; rowNum++){
Row rowData = sheet.getRow(rowNum);
if (rowData != null) {
EquipmentEntity equipmentEntity = new EquipmentEntity();
//设备编号
String number = String.valueOf(rowData.getCell(0));
if(number == "null"){
number = UUID.randomUUID().toString().substring(0,8);
equipmentEntity.setNumber(number);
}else {
number = number.substring(0,number.indexOf("."));
equipmentEntity.setNumber(number);
}
//设备名称
String name = String.valueOf(rowData.getCell(1));
if (name == "null"){
equipmentEntity.setName(name);
}else {
name = name.substring(0,name.indexOf("."));
equipmentEntity.setName(name);
}
//分类号
String classnum = String.valueOf(rowData.getCell(2));
if (classnum == "null"){
equipmentEntity.setClassnum(classnum);
}else {
classnum = classnum.substring(0,classnum.indexOf("."));
equipmentEntity.setClassnum(classnum);
}
//型号
String model = String.valueOf(rowData.getCell(3));
if(model == "null"){
equipmentEntity.setModel(model);
}else {
model = model.substring(0,model.indexOf("."));
equipmentEntity.setModel(model);
}
//规格
String specification = String.valueOf(rowData.getCell(4));
if (specification == "null"){
equipmentEntity.setSpecification(specification);
}else {
specification = specification.substring(0,specification.indexOf("."));
equipmentEntity.setSpecification(specification);
}
//单价
String jiage = String.valueOf(rowData.getCell(5));
if (jiage != "null") {
Double price = Double.valueOf(String.valueOf(jiage));
equipmentEntity.setPrice(price);
}
//厂商
String vendor = String.valueOf(rowData.getCell(6));
if (vendor == "null"){
equipmentEntity.setVendor(vendor);
}else {
vendor = vendor.substring(0,vendor.indexOf("."));
equipmentEntity.setVendor(vendor);
}
//出厂号
String factorynum = String.valueOf(rowData.getCell(7));
if (factorynum == "null"){
equipmentEntity.setFactorynum(factorynum);
}else {
factorynum = factorynum.substring(0,factorynum.indexOf("."));
equipmentEntity.setFactorynum(factorynum);
}
//购置日期
Date time = rowData.getCell(8).getDateCellValue();
if(time != null) {
equipmentEntity.setTime(time);
}else {
equipmentEntity.setTime(new Date());
}
//经费来源
String funding = String.valueOf(rowData.getCell(9));
equipmentEntity.setFunding(funding);
//归属单位
String deptnum = String.valueOf(rowData.getCell(10));
if (deptnum == "null"){
equipmentEntity.setDeptnum(deptnum);
}else {
deptnum = deptnum.substring(0,deptnum.indexOf("."));
equipmentEntity.setDeptnum(deptnum);
}
//设置设备仪器的默认属性值,状态为未分配
equipmentEntity.setStatus(0);
equipmentService.save(equipmentEntity);
}
}
//关闭流
inputStream.close();
return R.ok().put("url","成功");
}
}
注: ここでのデータベース保存のプロセスは多くのメモリを消費し、アップロードされたファイルの内容を読み取る際に行をたどってファイルを読み取るため、データベースへのアクセス操作が必要になるため、パフォーマンスを最適化する必要があります。情報の行が読み取られるたびに実行されます。行の数と同じくらい多くの IO 操作があり、パフォーマンスは良くありません。
3. まとめ
今日は以上が話しますが、この記事では Java コードを使用してファイルのアップロードとファイルのダウンロードを実装する方法を簡単に紹介するだけですので、お役に立てれば幸いです。