`
TableMiao
  • 浏览: 73798 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

文件上传、excel导入

阅读更多

文件上传到服务器

      java实现本地文件上传到服务器。

      实现方式:

            rest接口模式提供上传服务

      头文件:

         

        @POST       
	@Path("/upload")    
	@Consumes("multipart/form-data")
	@Produces("text/plain; charset=utf-8")

 

 

     

public synchronized String uploadDoc(MultipartFormDataInput input,
			@Context ServletContext servletContext) {
		logger.info("Began To Upload");
		Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
		List<InputPart> inputParts = uploadForm.get("Filedata");
		
		 //上传文件的web路径
		 String webPath = "/home/jike/tomcat-res1/webapps/shjkws";  
		 // 获取Web应用的路径	(也可以通过这种方式来获取)
		 //	final String realPath = servletContext.getRealPath(updatePath); 
		for (InputPart inputPart : inputParts) {
			try {
				//由于传输文件是以2进制的形式传输,所以通过流的方式读取文件名,避免中文名字乱码
				 InputPart a = uploadForm.get("Filename").get(0);
				 InputStream is = a.getBody(InputStream.class,
							null);
				//读取一遍名字
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				int i = -1;
				while ((i = is.read()) != -1) {
					baos.write(i);
				}
				String fileName = baos.toString("UTF-8");
				
				//也可以通过如下方式直接获取,不支持中文
				//String fileName = uploadForm.get("Filename").get(0)
				//		.getBodyAsString();
				logger.debug("上传文件的名字:{}",fileName);
				
				//截取上传文件后缀
				int pos = fileName.lastIndexOf('.');
				String fileTitle = fileName.substring(0, pos);//文件名字
				String fileHz = fileName.substring(pos);//文件后缀
				logger.debug("上传文件名称:{}  文件后缀:{}",fileTitle,fileHz);
				
				//自定义上传到服务器的文件格式,此处我定义的格式为
				//eg:知识库_故障报表20150428^20150428173419^.txt  
                                  //便于servlrt导出中文文件,详见文件下载、excel导出
				if (pos > 0) {
					fileName = "export" + File.separator + "知识库_"+fileTitle
							+ dayFormat.format(System.currentTimeMillis())
							+ fileHz;
				} else {
					fileName = "export" + File.separator + "知识库_"+fileTitle
					+ dayFormat.format(System.currentTimeMillis());
				}
				String realFile = webPath + File.separator + fileName;
				//查看文件是否存在,如果有就删掉,避免重复,根据需要使用
				fileOperate(realFile);
				//复制文件到服务器的另外位置,比如说部署了tomcat集群,挂了一个  
                                   //下载就找不到相应的路径,根据需要使用
				copyFile(realFile);
				
				//生成文件
				InputStream inputStream = inputPart.getBody(InputStream.class,
						null);
				File file = new File(realFile);
				FileUtils.copyInputStreamToFile(inputStream, file);
				logger.info("上传保存文件成功 返回生成的文件名:{}  , 真实路径 :{}", fileName,
						realFile);
				return fileName;
			} catch (Exception e) {
				throw new RuntimeException("上传文件异常!");
			}
		}
		return "没有上传文件!";
	}

 

   

      public void fileOperate(String realFile) {
		File file = new File(realFile);
		if (file.exists()) {
			logger.info("文件已经存在, 执行文件删除操作");
			file.delete();
			logger.info("删除已经存在的文件, 文件名称: {}", realFile);
		}
	}

	public void copyFile(String realFileName) {
		String webp = realFileName;
		if (!StringUtils.isEmpty(webPath2)) {
			logger.info("copying file: {}", realFileName);
			webp = webp.replace(webPath, webPath2);
			File file = new File(webp);
			if (file.exists())
				file.delete();
			try {
				FileUtils.copyFile(new File(realFileName), new File(webp));
			} catch (IOException e) {
				e.printStackTrace();
			}
			logger.info("file copied: {}", webp);
		}
	}

    前台界面,调用接口实现即可。

 

    excel数据导入到数据库

      比如把

 导入到



 

       界面上传一个excel拿到之后解析数据,可解析成一行一个map即数据为List<Map> 方式,也可解析成一行为一个实体bean即List<Bean>方式,解析模板不同而已……以下采取bean方式,更易于控制格式和理解。

       由于excel格式多样,所以解析映射bean的实体全部统一用String操作,当然也可以excel提供的cell.getCellType()来判断,时间转成数字格式也可以由DateUtil.isCellDateFormatted(cell)来判断,进行format。此处本人采用String格式,保证一系列的转码错误减少。

     1.excel解析的工具类

 

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

/***
 * 修改上传方式
 *    兼容 07和03 的excel
 * @author tablemiao
 *
 */
public class PoiExcelReader2 {
	
	public static <T> List<T> readExcelData(InputStream is, Class<T> clazz, Map<String, String> propMapper) {
		List<T> beans = new ArrayList<>();
		try {
			Workbook wbs = WorkbookFactory.create(is); 
	        Sheet sheet0 = wbs.getSheetAt(0);
			int rowCount = sheet0.getLastRowNum();

			if (rowCount > 0) {
				Row row0 = sheet0.getRow(0);
				Map<Integer, String> colMapper = createColMapper(row0, propMapper);
				for (int j = 1; j <= rowCount; j++) {
					Row row = sheet0.getRow(j);
					if (row == null)
						continue;
					T bean = rowToBean(row, colMapper, clazz);
					if (bean != null)
						beans.add(bean);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return beans;
	}
	
	private static <T> T rowToBean(Row row, Map<Integer, String> colMapper, Class<T> clazz){
		
	 SimpleDateFormat adf = new SimpleDateFormat("yyyy-MM-dd");
		
		try {
			T bean = clazz.newInstance();
			for(int i : colMapper.keySet()){
				Cell cell = row.getCell(i);
				Object value;				
				switch (cell.getCellType()) {
				case Cell.CELL_TYPE_STRING:
					value = cell.getRichStringCellValue().getString();
					break;
				case Cell.CELL_TYPE_NUMERIC:
					if (DateUtil.isCellDateFormatted(cell)) {
						value = adf.format(cell.getDateCellValue());
					} else {
						value = cell.getNumericCellValue();
					}
					break;
				case Cell.CELL_TYPE_BOOLEAN:
					value = cell.getBooleanCellValue();
					break;
				case Cell.CELL_TYPE_BLANK:
					value = "";
					break;
				default:
					value = "";
				}
				BeanUtils.setProperty(bean, colMapper.get(i), value);
			}
			return bean;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 分析第一行,确定对应关系
	 * @param row0 第一行,  保存对应列的意义
	 * @param propMapper  列的意义到bean属性的映射
	 * @return
	 */
	private static Map<Integer, String> createColMapper(Row row0, Map<String, String> propMapper){
		Map<Integer, String> colMapper = new HashMap<Integer, String>();
		int colCountR0 = row0.getLastCellNum();
		for (int i = 0; i < colCountR0; i++) {
			Cell cell = row0.getCell(i);
			if (propMapper.containsKey(cell.getStringCellValue())) {
				colMapper.put(cell.getColumnIndex(), propMapper.get(cell.getStringCellValue()));
			}
		}
		return colMapper;
	}
}

    通过

BeanUtils.setProperty(bean, colMapper.get(i), value);

 

     把excel中的数据一行转成一个实体bean,其中表头的列需要与数据库中字段一一对应,这是通过
propMapper  这个条件map来进行处理的

       excel数据解析完导入数据库方法

     

       Map<String, String> propMapper = new HashMap<String, String>();
	
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
	@PostConstruct//初始化 表头与数据库表字段对应的map
	private void initPropMapper() {
		propMapper.put("月份", "saveDate");
		propMapper.put("属地分公司", "dependency");
		propMapper.put("及时率(%)", "ratio");
	}

	@POST
	@Path("/upload")
	@Consumes("multipart/form-data")
	@Produces("text/plain; charset=utf-8")
	public synchronized Map<String, Object> uploadDoc(
			MultipartFormDataInput input, @Context ServletContext servletContext) throws Exception{
		logger.info("Began To Upload Excel Data!");
		Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
		List<InputPart> inputParts = uploadForm.get("Filedata");
		for (InputPart inputPart : inputParts) {
				InputStream inputStream = inputPart.getBody(InputStream.class,
						null);
                                //拿到excel中解析的数据,KpiIndexSZ.class为数据库表实体  字段类型全为String格式
				List<KpiIndexSZ> raas = PoiExcelReader2.readExcelData(
						inputStream, KpiIndexSZ.class, propMapper);

                             //到这里为止 就解析了上传excel中的数据,根据拿到的list再做新增,此时数据格式全部由String转码即可。根据具体需求新增

                      
				logger.debug("上传的excel数据为:{}",raas);
				if(raas.size()<=0||raas.isEmpty()||raas.get(0).getSaveDate()==null){
					throw new Exception("上传数据不能为空,上传失败");
				}
				for(KpiIndexSZ sz:raas){
					if(sz.getRatio()!=null&&!("".equals(sz.getRatio()))){
						if(!(NumberUtils.isNumber(sz.getRatio()))){
							throw new Exception("开通及时率必须为数字,上传失败");
						}
					}
					if(sz.getSaveDate()==null){
						throw new Exception("月份不能为空,上传失败");
					}		
					try{
						sdf.parse(sz.getSaveDate());
					}catch(Exception e){
						throw new Exception("月份不符合yyyy-MM格式,上传失败");
					}
				}
				// 得到excel上传数据的月份,去重,查库
				Map<String,String> monthMap = new HashMap<String, String>();
				for(KpiIndexSZ k:raas){
					monthMap.put(k.getSaveDate(), sdf.format(sdf.parse(k.getSaveDate())));
				}
				ArrayList<String> monthList = new ArrayList<String>(monthMap.values());
				
				KpiIndexSZExample example = new KpiIndexSZExample();
				example.createCriteria().andSaveDateIn(monthList);
				List<KpiIndexSZ> isEx = kpiIndexSZDao.selectByExample(example);
				Map<String, Object> resultMap = new HashMap<>();
				if(isEx.size()>0){
					//数据库存在,返回excel数据
					resultMap.put("isSuc", raas);
					logger.debug("excel中的数据:{}",raas);
				}else{
					//不存在,入库
					insert(raas);
					resultMap.put("isSuc", "上传成功");
				}
				return resultMap;
			}
		return null; 
	}
 

 记录一下上传接口 方便温习

  • 大小: 64 KB
  • 大小: 37.5 KB
1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics