`
gaosheng08
  • 浏览: 32227 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于excel的导入验证

阅读更多

目前公司接的项目都有很多功能的数据都要依靠excel导入,因此对excel中数据的验证必不可少。

先来看一下目前存在的问题:

一:在每处导入的程序中都会包括excel读取、数据验证、错误数据的导出或错误的输出,每次都是拷贝、粘帖、修改,本来不同的地方只有验证部分,但由于格式、验证的不同,在修改过程中还要对excel的读取、错误的导出进行修改、调试,造成工作效率的降低和时间的浪费。

二:由于人员更替频繁,每个人的风格都不一样,对于错误的显示和输出都不一样,客户看到的结果是每处导入的地方返回的错误结果也不一样,有的只是提醒一句成功、失败,有的则会把错误的记录导出excel供客户下载修改。客户对此也有很多抱怨。

解决思路:

在excel导入中我们关心的(也是唯一不同的)是数据的验证、保存,对于读取、错误记录导出并不关心,那就该把这两部分分离出来,这样的好处有:1.导入时不再关心excel的读取和错误信息的导出,编码及调试时不再为这部分付出时间和精力,加快开发效率。2.降低耦合度,目前对excel的操作使用的是jxl,如果以后改为poi那只需要需改excel操作的实现即可。3.统一,所有的导入使用相同的excel操作实现,如果excel读取操作有bug则只需修改一处(写此代码的起因就是一个同事出现的一个bug引起的),而且对错误记录的输出也有统一的输出。

解决办法:

限于本人的表达能力,要想讲清楚太费时间和篇幅了,在这里就直接上代码了

首先是抽象类 ImportDataMultiSheet,包括excel读取、错误记录导出的实现,支持多sheet及合并单元格的处理

 

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import org.gaosheng.util.exception.EntityException;

import jxl.Cell;
import jxl.CellType;
import jxl.DateCell;
import jxl.NumberCell;
import jxl.Range;
import jxl.Sheet;
import jxl.Workbook;
import jxl.format.Colour;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

/**
 * jxl导入excel类,继承类实现验证方法
 * 
 * @author gaosheng
 * 
 */
public abstract class ImportDataMultiSheet {

	private int startRow = 1;
	private int startColumn = 0;
	private int minRows = 1;
	private int minColumns = 1;
	private int maxRows = -1;
	private int maxColumns = -1;
	private Map<Integer, Method> methodMap;
	private Map<Integer, List<String>> holdColumns;
	private List<String>[] titiles ;
	private List<MeregRange> meregRangeList ;
	private Cell curCell;
	private Cell[] curRowCells;
	private int successcount = 0;
	
	private String[] columnMethods = null;
	private int[] needHoldColumns = null;
	private File importExcel;
	private File errorExcel;
	private boolean hasError = false;
	private List<String> errors = new ArrayList<String>();

	/**
	 * 启动导入
	 * 
	 * @return boolean
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws EntityException
	 */
	public boolean execute() throws SecurityException, NoSuchMethodException,
			EntityException {
		setMethodMap();
		setHoldColumns();
		Workbook work = null;
		try {
			work = Workbook.getWorkbook(importExcel);
		} catch (Exception e) {
			throw new EntityException("Excel表格读取异常!批量导入失败!<br/>");
		}

		//数据总行数
		int totalRows = 0;
		Sheet sheet = null;
		WritableWorkbook writew = null;
		WritableSheet writes = null;
		
		int sheet_num = work.getNumberOfSheets();
		// 全局验证
		if (!this.validGlobal(work.getSheets())) {
			throw new EntityException("导入文件格式错误");
		}
		try {
			for (int sheet_index = 0; sheet_index < sheet_num ;sheet_index++) {
				sheet = work.getSheet(sheet_index);
				meregRangeList = new ArrayList<MeregRange>();
				int columns = sheet.getColumns();
				int rows = sheet.getRows();
				totalRows += rows;

				for (Range range : sheet.getMergedCells()) {
					Cell topleft = range.getTopLeft();
					Cell bottomRight = range.getBottomRight();
					meregRangeList.add(new MeregRange(topleft.getRow(),topleft.getColumn(),bottomRight.getRow(),bottomRight.getColumn(),getCellValue(topleft)));
				}
				
				writew = Workbook.createWorkbook(errorExcel);
				writes = writew.createSheet("ErrorReport", 0);
				Label label;
				WritableCellFormat wcf;
				titiles = new List[startRow];
				List<String>	list = null;
				for (int i = 0; i < startRow; i++) {
					list = new ArrayList<String>();
					for (int j = 0; j < columns; j++) {
						label = new Label(j, i, getCellValue(sheet.getCell(j, i)));
						writes.addCell(label);
						list.add(getValue(sheet.getCell(j, i)));
					}
					titiles[i] = list;
				}
				label = new Label(columns, startRow - 1, "错误详细");
				WritableFont wf0 = new WritableFont(WritableFont.TIMES, 12);
				wcf = new WritableCellFormat(wf0);
				label.setCellFormat(wcf);
				writes.addCell(label);

				int wi = startRow;
				// -------------------------
				StringBuffer info_temp = null;
				String result = null;
				Method method = null;
				for (int i = startRow; i < rows; i++) {
					curRowCells = sheet.getRow(i);
					if (curRowCells == null || curRowCells.length < minColumns) {
						continue;
					}
					boolean[] wj = new boolean[columns];
					info_temp = new StringBuffer();
					for (int j = startColumn; j < columns; j++) {
						curCell = sheet.getCell(j, i);
						
//						System.out.print(String.format("%-30.30s", this.getValue(curCell))+"  ");
						result = everyCell();
						if (result != null) {
							method = methodMap.get(j);
							if (method == null) {
								continue;
							}
							result = (String) method.invoke(this, null);
						}
						if (result != null) {
							info_temp.append(result);
							info_temp.append(" ");
							wj[j] = true;
						}
						if (holdColumns.get(j) != null) {
							holdColumns.get(j).add(this.getValue(curCell));
						}
						if (info_temp.length() > 0) {
							errors.add("sheet "+sheet.getName()+" 中第 " + (i + 1) + " 行 :"
									+ info_temp.toString());
						}
					}
//					System.out.println();
					if (info_temp.length() > 1) {
						for (int ii = startColumn; ii < columns; ii++) {
							Cell c_temp = sheet.getCell(ii, i);
							label = new Label(ii, wi, c_temp.getContents().trim());
							wcf = new WritableCellFormat();
							if (wj[ii])
								wcf.setBackground(Colour.RED);
							label.setCellFormat(wcf);
							writes.addCell(label);
						}
						label = new Label(columns, wi, info_temp.toString());
						WritableFont wf = new WritableFont(WritableFont.TIMES,
								12);
						wf.setColour(Colour.RED);
						wcf = new WritableCellFormat(wf);
						label.setCellFormat(wcf);
						writes.addCell(label);
						wi++;
					} else {
						this.save();
						successcount ++;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			this.hasError = true;
			errors.add("sheet "+sheet.getName()+" 第"+this.curCell.getRow() +" 行 第 "+ this.curCell.getColumn()+" 列 :"+this.getCurCell().getContents()+" 遇到错误");
			return false;
		} finally {
			try {
				writew.write();
				writew.close();
				work.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (successcount < totalRows - sheet_num*startRow) {
			this.hasError = true;
		}
		return true;
	}

	/**
	 * 全局验证,验证对行数和列数的要求
	 * 
	 * @return
	 */
	public boolean validGlobal(Sheet[] sheets) {
		for (int i = 0; i < sheets.length; i++) {
			if (minRows != -1 && sheets[i].getRows() < minRows) {
				return false;
			} else if (minColumns != -1 && sheets[i].getColumns() < minColumns) {
				return false;
			} else if (maxRows != -1 && sheets[i].getRows() > maxRows) {
				return false;
			} else if (maxColumns != -1 && sheets[i].getColumns() > maxColumns) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 一行数据验证成功后保存
	 * @return boolean
	 */
	public abstract boolean save();
	
	/**
	 * 对每一个单元格进行的操作
	 * @return boolean
	 */
	public abstract String everyCell();
	
	/**
	 * 初始化存储验证列方法的Map
	 * 
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	@SuppressWarnings("unchecked")
	private void setMethodMap() throws SecurityException, NoSuchMethodException {
		methodMap = new HashMap<Integer, Method>();
		if (columnMethods == null) {
			Method[] methods = this.getClass().getMethods();
			for (int i = 0; i < methods.length; i++) {
				if (methods[i].getName().startsWith("validColumn_")) {
					String column = methods[i].getName().substring(
							methods[i].getName().indexOf("_") + 1);
					try {
						methodMap.put(Integer.parseInt(column), methods[i]);
					} catch (Exception e) {
						throw new NumberFormatException("默认列明必须为数字");
					}
				}
			}
		} else {
			Class<ImportDataMultiSheet> class1 = (Class<ImportDataMultiSheet>) this.getClass();
			for (int i = 0; i < columnMethods.length; i++) {
				methodMap.put(i, class1.getMethod(columnMethods[i], null));
			}
		}
	}

	/**
	 * 初始化存储保留列的Map,保留列用于验证某些列值时需引用其他列的情况
	 */
	private void setHoldColumns() {
		holdColumns = new HashMap<Integer, List<String>>();
		if (needHoldColumns == null) {
			return;
		}
		for (int i = 0; i < needHoldColumns.length; i++) {
			holdColumns.put(needHoldColumns[i], new ArrayList<String>());
		}
	}

	/**
	 * 获得给定单元格的实际值,对于时间会返回 'yyyy-MM-dd HH:mm:ss' 格式的字符串
	 * 
	 * @param cell
	 * @return String
	 */
	public static String getCellValue(Cell cell) {
		if (cell.getType().equals(CellType.NUMBER)) {
			return Double.toString(((NumberCell) cell).getValue());
		} else if (cell.getType().equals(CellType.DATE)) {
			TimeZone gmt = TimeZone.getTimeZone("GMT");
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
					Locale.getDefault());
			dateFormat.setTimeZone(gmt);
			return dateFormat.format(((DateCell) cell).getDate());
		} else if (cell.getType().equals(CellType.EMPTY)) {
			return null;
		} else {
			return cell.getContents().trim();
		}
	}

	public String getValue(Cell cell){
		String value = getCellValue(cell);
		if (value == null || getCellValue(cell).equals("")) {
			for(MeregRange meregRange:meregRangeList){
				if (meregRange.isInRange(cell.getRow(), cell.getColumn())) {
					return meregRange.getValue();
				}
			}
			return value;
		}else {
			return value;
		}
	}
	
	/**
	 * 防止空指针
	 * 
	 * @param object
	 * @return String
	 */
	public String fixNull(Object object) {
		return object == null ? "" : object.toString();
	}

	public int getMinRows() {
		return minRows;
	}

	public void setMinRows(int minRows) {
		this.minRows = minRows;
	}

	public int getMinColumns() {
		return minColumns;
	}

	public void setMinColumns(int minColumns) {
		this.minColumns = minColumns;
	}

	public int getMaxRows() {
		return maxRows;
	}

	public void setMaxRows(int maxRows) {
		this.maxRows = maxRows;
	}

	public int getMaxColumns() {
		return maxColumns;
	}

	public void setMaxColumns(int maxColumns) {
		this.maxColumns = maxColumns;
	}

	public String[] getColumnMethods() {
		return columnMethods;
	}

	public void setColumnMethods(String[] columnMethods) {
		this.columnMethods = columnMethods;
	}

	public File getImportExcel() {
		return importExcel;
	}

	public void setImportExcel(File importExcel) {
		this.importExcel = importExcel;
	}

	public File getErrorExcel() {
		return errorExcel;
	}

	public void setErrorExcel(File errorExcel) {
		this.errorExcel = errorExcel;
	}

	public boolean isHasError() {
		return hasError;
	}

	public int[] getNeedHoldColumns() {
		return needHoldColumns;
	}

	public void setNeedHoldColumns(int[] needHoldColumns) {
		this.needHoldColumns = needHoldColumns;
	}

	public Map<Integer, List<String>> getHoldColumns() {
		return holdColumns;
	}

	public int getStartRow() {
		return startRow;
	}

	public void setStartRow(int startRow) {
		this.startRow = startRow;
	}

	public int getStartColumn() {
		return startColumn;
	}

	public void setStartColumn(int startColumn) {
		this.startColumn = startColumn;
	}

	public Cell getCurCell() {
		return curCell;
	}

	public List<String> getErrors() {
		return errors;
	}

	public Cell[] getCurRowCells() {
		return curRowCells;
	}

	public List<String>[] getTitiles() {
		return titiles;
	}

	public int getSuccesscount() {
		return successcount;
	}

}

 

 下面是一个实现类的范例:

 

 

import java.io.File;
import java.util.List;

import jxl.Cell;

import org.gaosheng.util.exception.EntityException;
import org.gaosheng.util.xls.ImportDataMultiSheet;

public class ImportDatemultiImp extends ImportDataMultiSheet {

	public static void main(String[] args) throws SecurityException, NoSuchMethodException, EntityException {
		File importFile = new File("F:/test.xls");
		File errorFile = new File("F:/error.xls");
		ImportDatemultiImp importDateImp = new ImportDatemultiImp();
		importDateImp.setImportExcel(importFile);
		importDateImp.setErrorExcel(errorFile);
		importDateImp.setStartRow(1);
		importDateImp.execute();
		importDateImp.getErrorExcel();
		for (String error : importDateImp.getErrors()) {
			System.out.println(error);
		}
	}

	//对每一个单元格的执行的统一操作,返回值为错误信息,没有错误则返回null
	public String everyCell() {
		Cell cell = this.getCurCell();
		List<String>	semList = this.getTitiles()[2];
		List<String> courseList = this.getTitiles()[3];
		if (cell.getRow() > 3 && cell.getColumn() > 3) {
			String cellvalue = this.getValue(cell);
			String course_name = courseList.get(cell.getColumn());
			String reg_no = this.getValue(this.getCurRowCells()[1]); 
			String stuname = this.getValue(this.getCurRowCells()[2]);
			if (cellvalue != null && !cellvalue.equals("") && course_name !=null && !course_name.equals("") && reg_no != null && !reg_no.equals("")) {

			}else {
				return "无效成绩";
			}
		}
		return null;
	}

	//定义每一列的验证,默认方法名是validColumn_+列索引,也可以用setColumnMethods(String[] columnMethods)指定列的验证方法 返回值为错误信息,没有错误则返回null
	public String validColumn_1(){
		if (!this.getCurCell().getContents().equals("name")) {
			return "姓名错误";
		}
		return null;
	}
	
	public String validColumn_2(){
		if (!this.getCurCell().getContents().equals("passwd")) {
			return "密码错误";
		}
		return null;
	}

	public String validColumn_3(){
	
		return null;
	}

	//验证成功后保存记录
	public boolean save() {
		return false;
	}
}
 

 

 

分享到:
评论
7 楼 yylovelei 2012-03-19  
gaosheng08 写道
yylovelei 写道
gaosheng08 写道
yylovelei 写道
import org.gaosheng.util.exception.EntityException;

博主能把这个包贴出来吗?
谢谢了

这个是自定义的异常,随便实现就行


才看到你这个是jxl

对excel2007以上版本是不就不通用了??

对博主后来所写的excel2007
http://gaosheng08.iteye.com/blog/624758

是不就用不了了?

恩,是的,2007以上的一直没有写。



唉,水平有限啊,这下是判断不了了。
6 楼 gaosheng08 2012-03-18  
yylovelei 写道
gaosheng08 写道
yylovelei 写道
import org.gaosheng.util.exception.EntityException;

博主能把这个包贴出来吗?
谢谢了

这个是自定义的异常,随便实现就行


才看到你这个是jxl

对excel2007以上版本是不就不通用了??

对博主后来所写的excel2007
http://gaosheng08.iteye.com/blog/624758

是不就用不了了?

恩,是的,2007以上的一直没有写。
5 楼 yylovelei 2012-03-18  
gaosheng08 写道
yylovelei 写道
import org.gaosheng.util.exception.EntityException;

博主能把这个包贴出来吗?
谢谢了

这个是自定义的异常,随便实现就行


才看到你这个是jxl

对excel2007以上版本是不就不通用了??

对博主后来所写的excel2007
http://gaosheng08.iteye.com/blog/624758

是不就用不了了?
4 楼 gaosheng08 2012-03-18  
yylovelei 写道
import org.gaosheng.util.exception.EntityException;

博主能把这个包贴出来吗?
谢谢了

这个是自定义的异常,随便实现就行
3 楼 yylovelei 2012-03-16  
import org.gaosheng.util.exception.EntityException;

博主能把这个包贴出来吗?
谢谢了
2 楼 gaosheng08 2011-08-03  
fengmengcy 写道
请问这个类是MergeRange 是什么类

忘了贴了,是合并单元格的范围类
package org.gaosheng.util.xls.valid;

public class MeregRange {
	private int topleft_row ;
	private int topleft_column ;
	private int bottomRight_row ;
	private int bottomRight_column;
	private String value ;
	
	public MeregRange() {
		super();
	}

	public MeregRange(int topleft_row, int topleft_column, int bottomRight_row,int bottomRight_column){
		this(topleft_row, topleft_column, bottomRight_row, bottomRight_column, null);
	}
	
	public MeregRange(int topleft_row, int topleft_column, int bottomRight_row,int bottomRight_column,String value) {
		super();
		this.topleft_row = topleft_row;
		this.topleft_column = topleft_column;
		this.bottomRight_row = bottomRight_row;
		this.bottomRight_column = bottomRight_column;
		this.value = value;
	}
	
	public boolean isInRange(int row,int column) {
		if (row >= topleft_row && column >= topleft_column && row <= bottomRight_row && column <= bottomRight_column) {
			return true;
		}
		return false;
	}
	
	public int getTopleft_row() {
		return topleft_row;
	}
	public void setTopleft_row(int topleft_row) {
		this.topleft_row = topleft_row;
	}
	public int getTopleft_column() {
		return topleft_column;
	}
	public void setTopleft_column(int topleft_column) {
		this.topleft_column = topleft_column;
	}
	public int getBottomRight_row() {
		return bottomRight_row;
	}
	public void setBottomRight_row(int bottomRight_row) {
		this.bottomRight_row = bottomRight_row;
	}
	public int getBottomRight_column() {
		return bottomRight_column;
	}
	public void setBottomRight_column(int bottomRight_column) {
		this.bottomRight_column = bottomRight_column;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
	
}
1 楼 fengmengcy 2011-08-03  
请问这个类是MergeRange 是什么类

相关推荐

    Excel导入导及动态验证

    总结来说,结合JXL库和反射原理,我们可以实现高效且灵活的Excel导入导出功能,不仅能够方便地读写Excel文件,还能进行动态内容验证,确保数据的质量和一致性。这对于企业级应用中的数据处理和交互具有很大的价值。...

    验证EXCEL导入模板是否符合标准

    本话题主要探讨如何使用C#编程语言来验证Excel导入模板是否符合预设的标准,包括文件名、工作表名和字段名称的验证。 首先,我们需要理解验证的目标。一个标准的Excel导入模板应具有明确的命名规则,例如文件名可能...

    Java 使用poi导入excel 并使用xml做数据验证

    在本项目中,我们结合了POI库和XML技术来实现Excel数据的验证与导入数据库。 首先,Apache POI提供了HSSF和XSSF两个API,分别用于处理老版本的BIFF8格式(.xls)和新版本的OOXML格式(.xlsx)。在这个案例中,我们...

    easyexcel+validation excel导入导出下载

    本文将深入探讨如何结合EasyExcel和Validation实现高效且准确的Excel导入导出与数据校验。 EasyExcel的优势在于其简洁的API设计和对内存的高效利用。它无需预先加载整个Excel文件到内存,而是采用流式读写,降低了...

    excel导入动态校验,自定义注解动态校验

    本文将详细探讨"Excel导入动态校验,自定义注解动态校验"这一主题,旨在帮助你理解和掌握如何在处理Excel数据时进行有效的验证和校验。 首先,Excel导入动态校验是指在将Excel数据导入到系统或数据库时,对数据进行...

    pb9excel导入

    本文将深入解析这一操作的具体步骤、注意事项以及潜在的错误处理机制,为IT专业人士提供一个全面的PB9 Excel导入指南。 ### 一、PB9与Excel交互原理 在PB9中实现Excel文件导入主要依赖于OLE (Object Linking and ...

    .net的Excel导入

    在.NET框架中,处理Excel数据是一项常见的任务,特别是在构建企业级Web应用时,用户可能需要上传Excel文件...根据项目的具体需求选择合适的库,并确保处理好数据的读取、验证和存储,以提供高效且安全的Excel导入功能。

    C#实现Excel导入sqlite的方法

    总的来说,C#中实现Excel导入SQLite的过程涉及文件I/O、数据库操作、异常处理和UI交互等多个方面,这些知识点对于C#开发者来说都是基础且重要的技能。通过以上介绍,你应该能够理解如何在自己的项目中实现类似的功能...

    我的导入校验项目excel导入校验

    "我的导入校验项目excel导入校验"这个标题揭示了一个专注于使用Excel文件进行数据导入,并对数据进行复杂校验的项目。在这个过程中,用户或系统会将Excel表格中的数据提取出来,经过一系列验证规则的检查,然后将...

    C# 使用npoi导入excel 并使用xml做数据验证

    VS2012创建项目,这个是使用C#语言npoi2.1.3.0导入excel到数据库中,同时使用了xml对excel的每个单元格数据进行了非空验证。经测试,导入成功。数据库写入部分请自己完成。有问题请留言。已经在项目中运中复杂多表头...

    通过excel导入QC

    "通过Excel导入QC"是QC提供的一种功能,允许用户批量导入需求和测试用例数据,从而提高工作效率。本文将深入探讨如何利用Excel与QC进行数据交互,以及这一过程中的关键步骤和注意事项。 首先,我们需要了解Excel在...

    前端-HTML-Web Excel导入

    在前端开发中,Web Excel导入是一项常见的需求,它允许用户在网页上直接上传Excel文件,以便进行数据的读取、处理或展示。这项技术对于数据分析、报表制作等场景尤为重要。以下将详细介绍实现Web Excel导入涉及的...

    jeecg导入Excel

    1. **Excel导入原理**: Jeecg框架提供了对Excel数据导入的支持,其工作原理通常是读取Excel文件中的数据,然后按照预定义的映射规则,将这些数据存储到数据库中。这一过程涉及到了文件读取、数据解析、数据验证...

    java excel 导入手机号码(包括对手机的验证)

    * 此代码是完成从excel导入电话号码,将正确的电话号码保存到set集合中,因为set集合对于重复的值会覆盖,所以达到了去重复的值的用例,并累计了不正确的电话号码的个数,对电话号码进行了验证有效性。所需要的 dom4...

    excel导入SQL工具

    Excel导入SQL工具是一种实用软件,主要用于将Excel表格数据高效、便捷地导入到SQL数据库中。这类工具极大地简化了数据管理过程,特别是在处理大量结构化数据时,能够避免手动输入的繁琐工作,提高工作效率。 首先,...

    Excel导入导出 Excel导入 Excel导出

    "Excel导入导出"这一主题涵盖了如何将数据从外部源引入Excel以及如何将Excel数据导出到其他应用程序或格式。以下是对这一主题的详细解释: 1. **Excel导入**: - **CSV文件导入**:CSV(Comma Separated Values)...

    普元导入导出用于Excel导入导出

    在"普元导入导出 EOS 用于Excel导入导出"的场景下,我们可以探讨以下几个关键知识点: 1. **数据导入导出**: 这是系统与用户间交互的重要方式,允许用户通过Excel这样的工具来编辑和管理数据,然后将这些更改同步到...

    excel通过配置实现导入导出和校验

    2. **Excel导入**:导入Excel则是将用户填写的数据读取并存入数据库。在这个过程中,数据校验至关重要,以确保输入的数据符合业务规则。配置文件可以定义校验规则,如不能为空、必须是数字、日期格式正确等。当读取...

    thinkphp5 excel导入导出

    三、Excel导入 1. 使用PHPExcel导入Excel文件,首先需要创建一个PHPExcel对象,然后加载文件并读取数据: ```php use PHPExcel_IOFactory; $filePath = 'path/to/your/file.xlsx'; $inputFileType = PHPExcel_...

Global site tag (gtag.js) - Google Analytics