scala应用开发

上一篇知识储备的文章。

https://blog.youkuaiyun.com/qq_33792843/article/details/82735787

 

Scala项目代码结构

 

 

 

 

关于代码结构,我想说项目的主题部分吧。一步一步来。

因为签署了隐私协议,所以具体需求不能透露,以及涉及到业务的图片、代码都将被打上马赛克。

 

首先来看看主体akka部分代码。

 

以上为主题工程入口。

可以看到,在集成App类后,case Class JobTake就可以匹配到JobTaker中的receive方法。开始doStart

doStart为主要代码入口,但是在此之前,我们需要获取目标文件夹下文件的列表,来看该工具类。

package utils

import java.io.File

import common.Constants
import org.slf4j.LoggerFactory
import transform.AkkaActor

import scala.collection.mutable.ListBuffer


/**
  * 文件
  * @author shouzhuang.li on 2018/09/11
  */
class FileUtils {

  val logger = LoggerFactory.getLogger(AkkaActor.getClass.getName)

  /**
    * 获取指定路径下文件
    * @return
    */
  def getFileList():ListBuffer[File]= {
    val nowPath = System.getProperty(Constants.USER_IDR) //user.dir指定了当前的路径
    val list = subdir(new File(nowPath + Constants.INPUT_PATH))
    if(null == list) return null else if (list.isEmpty) {new MsgBoxUtils().sendWrongMsg(Constants.LOG_ERROR + "输入文件内没有可用文件,请检查.");return null}
//    list.foreach{x=>logger.info("即将处理文件 : {} ",x.getAbsolutePath)}
    logger.info("即将处理文件 : {} ",list.mkString("[",", ","]"))

    list
  }


  /**
    * 获取指定目录下所有文件,过滤文件夹
    * @param dir
    * @return
    */
  def subdir(dir:File):  ListBuffer[File]={
    val listFiles:Array[File]=dir.listFiles()
    val list = new ListBuffer[File]
    try{
      for (file <- listFiles if file.isFile;if file.getName.contains(Constants.SALARY_EXCEL_FLAG)) list.append(file)
    }catch {
      case e:NullPointerException=>new MsgBoxUtils().sendWrongMsg(Constants.LOG_ERROR + " 输入文件目录不存在,请仔细检查!");return null
      case e:Exception=> new MsgBoxUtils().sendWrongMsg(e.getMessage);;return null
    }
    list
  }

}

在刚才的akkaActor获取list后,如果也没有异常,就会进入具体方法。

代码逻辑如下。

package transform

import java.io.File

import common.Constants
import org.slf4j.LoggerFactory
import utils.{MsgBoxUtils, TimeUtils}

class HandlerJob {
  val logger = LoggerFactory.getLogger(AkkaActor.getClass.getName)


  /**
    * 开启线程run方法
    * @param file
    */
  def doStart(file: File): Unit = {
    logger.info(Constants.LOG_START_FLAG ,file.getName)

    /* 1.校验所有sheet完备性 */
    logger.info(Constants.LOG_STEP1_FLAG)
    val validXlsx = new ValidXlsx()
    val validFlagString = validXlsx.reedXlsxAndValid(file.getPath)
    if (validFlagString.length!=Constants.ZERO_INDEX) {new MsgBoxUtils().sendWrongMsg(validFlagString);return }


    logger.info(Constants.LOG_STEP2_FLAG)
    val getExcelData = new GetExcelData()
    val allPersonMap = getExcelData.getExcelDataMethod(file.getPath)
    if(null == allPersonMap || allPersonMap.isEmpty){ new MsgBoxUtils().sendWrongMsg("解析内容为空,请检查输入内容.");return }


    logger.info(Constants.LOG_STEP3_FLAG)
    val company = new CombineDeptAndCom().combineDeptsAndCom(allPersonMap)


    logger.info(Constants.LOG_STEP4_FLAG)
    new Calculate().calculate(company)


    try{
      logger.info(Constants.LOG_STEP5_FLAG)
      val outputPath = file.getParent.replace(Constants.SALARY_FILE_INPUT, Constants.SALARY_FILE_OUTPUT)
      logger.info(Constants.OUTPUT_FILEPATH ,outputPath)
      val filenameUnFilter = file.getName.replace(".xlsx", "")
      val filename = Constants.LOG_FILENAME_STRING.format(filenameUnFilter, (new TimeUtils).getTimestamps())
      logger.info(Constants.LOG_OUTPUT_STRING ,filename)
      new WriteExcel().writeExcel(company, outputPath, filename)

    }catch {
      case e:Exception=>{
        logger.error(Constants.LOG_ERROR+e.getMessage)
        new MsgBoxUtils().sendWrongMsg(e.getMessage)
      }
    }

    logger.info(Constants.LOG_END)
  }
}

第一步,校验excel的完整性。

package transform

import java.io.{FileInputStream, FileNotFoundException}

import common.Constants
import org.apache.poi.ss.usermodel.{Sheet, Workbook}
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.slf4j.LoggerFactory
import utils.CommonUtils

/**
  * 校验excel模块
  *
  * @author shouzhuang.li on 2018/09/11
  */
class ValidXlsx {

  val logger = LoggerFactory.getLogger(AkkaActor.getClass.getName)

  /**
    * 读取Excel,兼容 Excel 2003/2007/2010
    *
    * @param path
    * @return List<String>
    */
  def reedXlsxAndValid(path: String): String = {
    try{val is = new FileInputStream(path)

    if (null == is) return Constants.ERROR_FLAG


    val workbook = new XSSFWorkbook(is)
    if (null == workbook) return Constants.ERROR_FLAG

    /* 输入文件总校验 */
    val validExcel = doVilidExcel(workbook)
    if (validExcel == null || validExcel.length > Constants.ZERO_INDEX) return validExcel

    //校验sheet1表头
    val sheet0 = workbook.getSheetAt(Constants.ZERO_INDEX)
    val sheet0StandardHead = Constants.SHEET0_LIST_STANDARD_STR.split(Constants.STRING_SPLITION).size
    val excelHeadSheet1 = validExcelHead(sheet0,sheet0StandardHead, Constants.SHEET0_LIST_STANDARD_STR)
    if(excelHeadSheet1.length != Constants.ZERO_INDEX) return excelHeadSheet1

    //校验sheet2表头
    val sheet1 = workbook.getSheetAt(Constants.ONE_INDEX)
    val sheet1StandardHead = Constants.SHEET1_LIST_STANDARD_STR.split(Constants.STRING_SPLITION).size
    val excelHeadSheet2 = validExcelHead(sheet1,sheet1StandardHead, Constants.SHEET1_LIST_STANDARD_STR)
    if(excelHeadSheet2.length != Constants.ZERO_INDEX) return excelHeadSheet2

    }catch {
      case e :FileNotFoundException=> return e.getMessage
    }

    ""
  }


  /**
    * 校验表头字段是否齐整
    *
    * @param sheet
    * @return
    */
  def validExcelHead(sheet: Sheet, column: Int, listStand: String): String = {
    val sheetListStand = listStand.split(Constants.STRING_SPLITION, -1).toList
    val row = sheet.getRow(Constants.ZERO_INDEX)
    //总列数
    val columnNum = row.getPhysicalNumberOfCells
    if (columnNum < column) return "该sheet : %s  内列字段不够,缺少必要字段,请检查!".format(sheet.getSheetName)


    //为了获取标准字段以及所给excel字段是否涵盖
    var listExcelString = ""
    for (i <- 0 until columnNum) {
      val cellValue = new CommonUtils().getCellValue(row.getCell(i))
      if (columnNum - 1 == i) listExcelString = listExcelString + cellValue else listExcelString = listExcelString + cellValue + Constants.STRING_SPLITION
    }
    val listExcel = listExcelString.split(Constants.STRING_SPLITION, -1).toList
    if (listExcel.isEmpty) return "该sheet : %s  内列字段不够,缺少必要字段,请检查!".format(sheet.getSheetName)  //如果excel中没有表头数据


    //这里是为了校验两个list的自己关系
    val initBoolean = list1containslist2(listExcel, sheetListStand)
    if (!initBoolean) {
      val excelHeadName = findList1containslist2(listExcel, sheetListStand)
      if (null != excelHeadName && !"".equalsIgnoreCase(excelHeadName)) return sheet.getSheetName + Constants.SHORT_OF_COLUMNNAME + sheet.getSheetName + " : " + excelHeadName
      return Constants.ERROR_FLAG
    }

    ""
  }


  /**
    * 为了校验:
    * 1.workbook不为空
    * 2.sheet不为空
    * 3.sheet名称
    * 4.row记录数是否为空
    *
    * @param workbook
    * @return
    */
  def doVilidExcel(workbook: Workbook): String = {
    var message = validSheet(Constants.ZERO_INDEX, workbook)
    if(message.length > Constants.ZERO_INDEX) return message
    message = validSheet(Constants.ONE_INDEX, workbook)
    message
  }


  /**
    * 根据具体的sheet类型,处理其中校验
    * @param sheetType
    * @param workbook
    * @param m
    * @return
    */
  def validSheet(sheetType: Int, workbook: Workbook): String = {
    var message,sheetName = ""
    if (Constants.ZERO_INDEX == sheetType) sheetName = Constants.SHEET1_NAME_STRING else sheetName = Constants.SHEET2_NAME_STRING

    if(workbook.getNumberOfSheets <2 ) return "该excel数小于2,请检查!"
    val sheet = workbook.getSheetAt(sheetType) //获取sheet

    if (!sheetName.equalsIgnoreCase(sheet.getSheetName)) {
      message += sheetName + Constants.SHEET_NAME_UNVILID
    } else {
      //获取总行数
      if (sheet.getPhysicalNumberOfRows() < 2)  message += sheetName + Constants.SHEET_DATA_EMPTY
    }
    message
  }


  /**
    * 判断是否标准集合在给入集合里面没有
    * 子集判断方法
    *
    * @param list1
    * @param list2
    * @return
    */
  def list1containslist2(list1: Seq[String], list2: Seq[String]): Boolean = {
    var trueOrFalse = true
    list2.foreach { x =>  if (!list1.contains(x)) trueOrFalse = false}
    trueOrFalse
  }


  /**
    * 该方法用于返回是哪些字段没有
    *
    * @param list1
    * @param list2
    * @return
    */
  def findList1containslist2(list1: Seq[String], list2: Seq[String]): String = {
    var unHaveExcelHead = ""
    list2.foreach { x =>  if (!list1.contains(x)) unHaveExcelHead = unHaveExcelHead + x + " "  }
    unHaveExcelHead
  }


}

 

校验完了之后,来到最精彩的构建环节。

然后是输出了。

可以看到代码非常的简洁,没有任何的拖泥带水。

总体感觉非常优雅,好了。我的第一个即将投产的scala应用完了,后续还会有更多的Java、python、scala应用,开发hadoop、spark做离线,实时处理,敬请期待。

你与我一同进步,成为那改变世界的人。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值