Java实现Excel模板的复制,并利用Java反射往新的Excel文件中的指定行开始写入数据

这两天实现了将对账单中的数据导入excel表中的功能,具体需求如下:

首先需要复制一份公共的对账单excel模板,然后往新复制的excel模板文件中从第四行开始(因为前面三行是表头信息,规定的格式,不能修改)写入具体的数据。

 

先导入需要的jar包:

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>3.9</version>
		</dependency>

 

这里,复制excel文件和往excel表中写入数据,我分别封装在了两个方法中,直接上代码:


/**    
* @Title: ExcelUtils.java  
* @date 2019年3月18日  
* @version V1.0    
*/

package demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


/**
 * @ClassName: ExcelUtils
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author hqq
 * @date 2019年3月18日
 * 
 */
public class ExcelUtils {

	private static final Logger logger = Logger.getLogger(TimerTaskServiceImpl.class);


	/**
	 * 利用java反射,将java实体类中的数据写入到excel表格中
	 * @param excelUrl 要写入数据的excel表格的绝对路径
	 * @param dateList 要写入excel表格的数据集
	 * @param classType 封装数据的实体类类型
	 * @param startRow 从excel表格的第 startRow行开始写入数据。假如是从第三行开始写入数据,那么startRow=2
	 * @param total 写入实体类中的前 total 个字段的数据,因为一个实体类可能有很多字段,但是只有部分字段是需要使用的,并且,实体类中的字段顺序应保持与excel表中每个指定单元格的位置一致,否则会造成写入的数据混乱或失败
	 */
	public static void appendDateToExcel(String excelUrl, List<?> dateList, Class<?> classType, 
			int startRow, int total) throws Exception {
		
		FileInputStream fs = null;
		FileOutputStream out = null;
		HSSFWorkbook wb = null;
		try {
			
			Field[] fields = classType.getDeclaredFields();// 得到对象中的字段
			
			fs = new FileInputStream(excelUrl); // 获取head.xls
			
			POIFSFileSystem ps = new POIFSFileSystem(fs); // 使用POI提供的方法得到excel的信息
			wb = new HSSFWorkbook(ps);
			HSSFSheet sheet = wb.getSheetAt(0); // 获取到工作表,因为一个excel可能有多个工作表
			
			out = new FileOutputStream(excelUrl); // 向head.xls中写数据
			// 利用反射获取对象中的所有字段
			Field field = null;
			String fieldName = null;
			String getMethodName = null;
			Method getMethod = null;
			HSSFRow row = null;
			String type = null;
			Object obj = null;
			Object o = null;
			
			int num=0;
			// 遍历所有的对象
			for (int i = 0, k = startRow; i < dateList.size(); i++, k++) {
				o = dateList.get(i);
				
				// 从指定行开始写入,如果是第3行开始写,则k=2(excel中的行默认从0开始)
				row = sheet.createRow((short) (k));
				
				//因为我的excel表中每一行的第一个单元格都是序号,此处可按需要修改
				row.createCell(0).setCellValue(++num);
				
				// 一个实体类中可能有很多字段,但是只有部分字段才是我们需要的,将需要的字段放在实体类中的最前面,并设置读取位置
				for (int j = 0; j < total; j++) {
					
					field = fields[j];
					fieldName = field.getName();
					getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
					getMethod = classType.getMethod(getMethodName);
					
					obj = getMethod.invoke(o);// 调用对象的getXXX方法
					
					// 这个字段是空值,就取消写入
					if (obj == null) {
						continue;
					}
					
					
					// 获取属性类型
					type = field.getGenericType().toString();
					
					switch (type) {
					case "class java.lang.String":
						row.createCell(j+1).setCellValue((String) obj);
						break;
					case "class java.lang.Integer":
						row.createCell(j+1).setCellValue((Integer) obj);
						break;
					case "class java.lang.Double":
						row.createCell(j+1).setCellValue((Double) obj);
						break;
					case "class java.lang.Boolean":
						row.createCell(j+1).setCellValue((Boolean) obj);
						break;
					case "class java.util.Date"://日期类型的数据直接转换成字符串格式写入,否则读到excel表后可能无法识别
						row.createCell(j+1).setCellValue(DateUtil.format((Date) obj));
						break;
					default:
						row.createCell(j+1).setCellValue((String) obj);
						break;
					}
				}
			}
			
		} catch (Exception e) {
			logger.info("往excel表中写入数据异常:" + e.getMessage());
			throw e;
		} finally {
			try {
				if (out != null) {
					out.flush();
				}
				
				if (wb != null) {
					wb.write(out);
				}
				
				if (out != null) {
					out.close();
				}
			} catch (Exception e) {
				logger.info("往excel表格写入数据异常:"+e.getMessage());
			}
		}
		
	}

	/**
	 * 复制excel表格,该excel表格的格式应该是.xls
	 * @param modelExcel 模板excel文件的路径
	 * @param newExcel 新复制的excel文件需要保存的路径
	 * @param newName 新复制的excel文件的文件名
	 */
	public static void copyExcel(String modelExcel, String newExcel,String newName) {
		HSSFWorkbook wb = null;
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			
			File file=new File(newExcel);
			if(!file.exists()){
				file.mkdirs();
			}
			fis = new FileInputStream(modelExcel);
			fos = new FileOutputStream(newExcel+"/"+newName);
			wb = new HSSFWorkbook(fis);
			wb.write(fos);
		} catch (Exception e) {
			logger.info("复制excel表格异常1:" + e.getMessage());
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
				if (fos != null) {
					fos.close();
				}
			} catch (IOException e) {
				logger.info("复制excel表格异常2:" + e.getMessage());
			}
		}
	}

}

 

此处节选部分调用该工具类的代码:

@Override
	public void genOrderStatementExcel(List<OrderStatementInfo> list) {
		
		try {
			
			//模板文件的绝对路径
			String modelExcel = "D:/model.xls";
			
			String fileName="newfile.xls";
			
                //复制模板
			ExcelUtils.copyExcel(modelExcel, "D:/bill/",fileName);
			
			//新文件的路径
			fileName="D:/bill/"+fileName;
			
                //往文件中写数据
			ExcelUtils.appendDateToExcel(fileName, list, OrderStatementInfo.class, 3, 38);
			
			//此处隐藏核心业务		
			
		} catch (Exception e) {
			
		}
	}

粘上部分实体类的信息,注意实体类的字段顺序应该与excel表中的单元格列顺序保持一致,否则反射写入时会写错:

 

截取部分写入成功之后的excel表信息:

 

至此,功能实现!

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用 Apache POI 库来读取和写入 Excel 文件。以下是一个使用 Apache POI 的示例代码,它使用 HSSFWorkbook 类来读取和写入 Excel: ```java org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.*; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class ExcelUtils { public static void readExcel(String filePath, int startRow) { try { FileInputStream fis = new FileInputStream(filePath); Workbook workbook = new HSSFWorkbook(fis); Sheet sheet = workbook.getSheetAt(0); for (int i = startRow; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); Cell cell = row.getCell(0); // Assuming you want to read data from the first column System.out.println(cell.getStringCellValue()); } fis.close(); } catch (IOException e) { e.printStackTrace(); } } public static void writeExcel(String filePath, int startRow, String data) { try { FileInputStream fis = new FileInputStream(filePath); Workbook workbook = new HSSFWorkbook(fis); Sheet sheet = workbook.getSheetAt(0); Row row = sheet.getRow(startRow); Cell cell = row.createCell(0); // Assuming you want to write data to the first column cell.setCellValue(data); FileOutputStream fos = new FileOutputStream(filePath); workbook.write(fos); fos.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { String filePath = "path/to/your/excel/file.xls"; int startRow = 1; // Assuming you want to start reading/writing from the second row readExcel(filePath, startRow); writeExcel(filePath, startRow, "New Data"); } } ``` 请确保将 `path/to/your/excel/file.xls` 替换为您实际的 Excel 文件路径。`startRow` 参数表示您要从哪一开始读取或写入数据。示例代码使用的是 HSSFWorkbook 类,适用于 `.xls` 格式的 Excel 文件。如果您使用的是 `.xlsx` 格式的 Excel 文件,可以使用 XSSFWorkbook 类。 希望这可以帮助到您!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值