Prefacio
Durante el desarrollo del proyecto, a veces se utilizan funciones de carga y descarga de archivos. El proyecto proporciona una plantilla para que los usuarios la descarguen. Después de que el usuario la descargue, agregue el contenido de datos requerido y cárguelo en el proyecto. El backend del proyecto recibe el archivo y lo analiza. Si es necesario guardarlo en la base de datos, lo realizar operaciones relacionadas con la base de datos.Entonces, ¿cómo implementar la función de carga y descarga de archivos? El siguiente caso es como referencia (este proyecto se basa en Springboot, el marco usa el marco de permisos de todos y la interacción front-end y back-end usa comunicación ajax).
1. Descargue el archivo de plantilla
1. Cree un enlace de descarga del archivo de plantilla en la interfaz
<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. Escritura de la interfaz de back-end
Agregar dependencias del proyecto
<!-- 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. La ubicación de la plantilla de archivo en la interfaz de backend.
Nota : La ubicación de este archivo de plantilla se encuentra en la carpeta de recursos, que está al mismo nivel que las plantillas.
2. Cargue archivos e importe datos a la base de datos.
1. Cree un botón de carga de archivos en la interfaz
<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. clase de entidad
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. Escritura de la interfaz de back-end
@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","成功");
}
}
Nota : El proceso de almacenamiento de la base de datos aquí ocupa mucha memoria y es necesario optimizar el rendimiento. La razón es que al leer el contenido del archivo cargado, el archivo se lee atravesándolo en líneas separadas y el La operación de acceso a la base de datos se realiza cada vez que se lee una línea de información. Hay tantas operaciones de IO como filas y el rendimiento no es bueno.
3. Resumen
Lo anterior es de lo que hablaré hoy. Este artículo solo presenta brevemente el uso del código Java para implementar la carga y descarga de archivos. Espero que pueda ayudarlo.