Răsfoiți Sursa

Merge remote-tracking branch 'origin/Verification_of_Analytical_Performance' into matser

Li Yuan 2 ani în urmă
părinte
comite
19d0b25af4
27 a modificat fișierele cu 2700 adăugiri și 6 ștergeri
  1. 6 1
      ibps-component-root/modules/comp-poi/src/main/java/com/lc/ibps/components/poi/excel/export/ExcelExportServer.java
  2. 5 5
      ibps-component-root/modules/comp-poi/src/main/java/com/lc/ibps/components/poi/excel/imports/ExcelImportServer.java
  3. 5 0
      ibps-provider-root/modules/provider-business/pom.xml
  4. 127 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/controller/PerformanceVerificationController.java
  5. 161 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/CreateExcelScatterChart.java
  6. 160 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelExportReportServer.java
  7. 101 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelExportStyler.java
  8. 44 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelExportTemplateServer.java
  9. 114 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelImportServer.java
  10. 184 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelUtil.java
  11. 135 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVTest.java
  12. 38 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/TestFuncs.java
  13. 29 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xAverage.java
  14. 121 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xFuncArray2Args.java
  15. 50 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xFuncStdevVar.java
  16. 20 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xLog10.java
  17. 613 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xValue.java
  18. 23 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/ExcelParserErrorEnum.java
  19. 67 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/ExcelSheetRecord.java
  20. 24 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/FunctionEnum.java
  21. 123 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/InspectionConfigVO.java
  22. 257 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/InspectionItemVO.java
  23. 42 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/InspectionVO.java
  24. 61 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/ItemCalcVO.java
  25. 116 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/SpecimensCalcVO.java
  26. 18 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/service/PerformanceVerificationService.java
  27. 56 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/service/impl/PerformanceVerificationServiceImpl.java

+ 6 - 1
ibps-component-root/modules/comp-poi/src/main/java/com/lc/ibps/components/poi/excel/export/ExcelExportServer.java

@@ -198,6 +198,7 @@ public class ExcelExportServer extends ExcelExportBase {
             } else {
                 // 创建合计信息
                 addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet);
+                postHanderSheet(sheet,dataSet);
             }
 
         } catch (Exception e) {
@@ -206,13 +207,16 @@ public class ExcelExportServer extends ExcelExportBase {
         }
     }
 
+    protected void postHanderSheet(Sheet sheet,Collection<?> dataSet) {
+    }
+
     /**
      * 创建表头
      * 
      * @param title
      * @param index
      */
-    private int createTitleRow(ExportParams title, Sheet sheet, Workbook workbook, int index,
+    protected int createTitleRow(ExportParams title, Sheet sheet, Workbook workbook, int index,
                                List<ExcelExportEntity> excelParams) {
         Row row = sheet.createRow(index);
         int rows = getRowNums(excelParams);
@@ -234,6 +238,7 @@ public class ExcelExportServer extends ExcelExportBase {
                 if (StringUtils.isNotBlank(entity.getName())) {
                     sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex,
                         cellIndex + sTitel.size() - 1));
+                    createStringCell(row, cellIndex + sTitel.size() - 1, "", titleStyle, entity);
                 }
                 for (int j = 0, size = sTitel.size(); j < size; j++) {
                     createStringCell(rows == 2 ? listRow : row, cellIndex, sTitel.get(j).getName(),

+ 5 - 5
ibps-component-root/modules/comp-poi/src/main/java/com/lc/ibps/components/poi/excel/imports/ExcelImportServer.java

@@ -67,7 +67,7 @@ public class ExcelImportServer extends ImportBaseService {
 
 	private CellValueServer cellValueServer;
 
-	private boolean verfiyFail = false;
+	protected boolean verfiyFail = false;
 	/**
 	 * 异常数据styler
 	 */
@@ -120,7 +120,7 @@ public class ExcelImportServer extends ImportBaseService {
 	 * @param cell
 	 * @return
 	 */
-	private String getKeyValue(Cell cell) {
+	protected String getKeyValue(Cell cell) {
 		Object obj = PoiCellUtil.getCellValue(cell);
 		return obj == null ? null : obj.toString().trim();
 	}
@@ -145,7 +145,7 @@ public class ExcelImportServer extends ImportBaseService {
 		return excelImportEntity.getSaveUrl();
 	}
 
-	private <T> List<T> importExcel(Collection<T> result, Sheet sheet, Class<?> pojoClass, ImportParams params,
+	protected  <T> List<T> importExcel(Collection<T> result, Sheet sheet, Class<?> pojoClass, ImportParams params,
 			Map<String, PictureData> pictures) throws Exception {
 		List collection = new ArrayList();
 		Map<String, ExcelImportEntity> excelParams = new HashMap<String, ExcelImportEntity>();
@@ -301,7 +301,7 @@ public class ExcelImportServer extends ImportBaseService {
 	 * @param excelCollection
 	 * @return
 	 */
-	private Map<Integer, String> getTitleMap(Iterator<Row> rows, ImportParams params,
+	protected Map<Integer, String> getTitleMap(Iterator<Row> rows, ImportParams params,
 			List<ExcelCollectionParams> excelCollection) {
 		Map<Integer, String> titlemap = new HashMap<Integer, String>();
 		Iterator<Cell> cellTitle;
@@ -531,7 +531,7 @@ public class ExcelImportServer extends ImportBaseService {
 		}
 	}
 
-	private void createErrorCellStyle(Workbook workbook) {
+	protected void createErrorCellStyle(Workbook workbook) {
 		errorCellStyle = workbook.createCellStyle();
 		Font font = workbook.createFont();
 		font.setColor(Font.COLOR_RED);

+ 5 - 0
ibps-provider-root/modules/provider-business/pom.xml

@@ -62,6 +62,11 @@
 			<artifactId>pdfbox</artifactId>
 			<version>2.0.24</version>
 		</dependency>
+		<dependency>
+			<groupId>org.apache.poi</groupId>
+			<artifactId>ooxml-schemas</artifactId>
+			<version>1.4</version>
+		</dependency>
 
 		<!-- 北京CA电子签章jar包   -->
 		<dependency>

+ 127 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/controller/PerformanceVerificationController.java

@@ -0,0 +1,127 @@
+package com.lc.ibps.components.verification.controller;
+
+import com.lc.ibps.api.base.constants.StateEnum;
+import com.lc.ibps.cloud.entity.APIResult;
+import com.lc.ibps.cloud.provider.GenericProvider;
+import com.lc.ibps.components.verification.model.InspectionItemVO;
+import com.lc.ibps.components.verification.service.PerformanceVerificationService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+@Validated
+@Api(tags = "性能验证接口")
+@RequestMapping(value = "/pv")
+@RestController
+public class PerformanceVerificationController extends GenericProvider{
+
+    protected static final Logger logger = LoggerFactory.getLogger(PerformanceVerificationController.class);
+    @Autowired
+    private PerformanceVerificationService performanceVerificationService;
+
+
+    @PostMapping(value = "/importExcelRecord",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    @ApiOperation("导入检测数据")
+    public APIResult<Void> importExcelRecord(@RequestParam(value = "name") String name,
+                                             @RequestParam(value = "id") String id,
+                                             @RequestPart(value = "applyFiles") MultipartFile applyFiles
+    ) {
+        APIResult<Void> apiResult = new APIResult<>();
+        InspectionItemVO itemVO = null;
+        try {
+            itemVO = performanceVerificationService.importExcelRecord(name, id, applyFiles);
+            if (itemVO.isDataPass()) {
+                apiResult.setMessage("导入成功");
+                apiResult.setState(StateEnum.SUCCESS.getCode());
+            } else {
+                apiResult.setMessage("数据校验失败");
+                apiResult.setState(StateEnum.ERROR.getCode());
+//            apiResult.setVariables(itemVO.getErrorMessage());
+            }
+        } catch (IOException e) {
+            apiResult.setMessage("导入失败");
+            apiResult.setState(StateEnum.ERROR.getCode());
+        }
+
+
+        return apiResult;
+    }
+
+    @PostMapping("/exportExcelTemplate")
+    @ApiOperation(value = "导出数据模板", notes = "导出数据模板")
+    public  APIResult<Void> exportExcelTemplate(@RequestParam(value = "name") String name,
+                                    @RequestParam(value = "id") String id) {
+        ByteArrayOutputStream bos = null;
+        APIResult<Void> apiResult = new APIResult<>();
+        try {
+
+            Workbook workbook = performanceVerificationService.exportExcelTemplateExport(name, id);
+//			String rootRealPath = AppFileUtil.getRealPath("/" + AppFileUtil.TEMP_PATH); // 操作的根目录
+            String fileName = "dataTemplate_" + name + (workbook instanceof HSSFWorkbook ? ".xls" : ".xlsx");
+//			FileUtil.writeFile(rootRealPath + File.separator + fileName + (workbook instanceof HSSFWorkbook ? ".xls" : ".xlsx"), workbook);
+            bos = new ByteArrayOutputStream();
+            workbook.write(bos);
+            byte[] barray = bos.toByteArray();
+            com.lc.ibps.base.web.util.RequestUtil.downLoadFileByByte(this.getRequest(), this.getResponse(), barray, fileName);// 导出
+            apiResult.setMessage("导出成功");
+            apiResult.setState(StateEnum.SUCCESS.getCode());
+        } catch (Exception e) {
+            logger.error("/pv/exportExcelTemplate", e);
+            apiResult.setMessage("导出失败");
+            apiResult.setState(StateEnum.ERROR.getCode());
+        } finally {
+            if (bos != null) {
+                try {
+                    bos.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return apiResult;
+    }
+    @PostMapping("/exportExcelReport")
+    @ApiOperation(value = "导出数据报告", notes = "导出数据报告")
+    public  APIResult<Void> exportExcelReport(@RequestParam(value = "name") String name,
+                               @RequestParam(value = "id") String id) {
+        ByteArrayOutputStream bos = null;
+        APIResult<Void> apiResult = new APIResult<>();
+        try {
+
+            Workbook workbook = performanceVerificationService.exportExcelReport(name, id);
+//			String rootRealPath = AppFileUtil.getRealPath("/" + AppFileUtil.TEMP_PATH); // 操作的根目录
+            String fileName = "dataReport_" + name + (workbook instanceof HSSFWorkbook ? ".xls" : ".xlsx");
+//			FileUtil.writeFile(rootRealPath + File.separator + fileName + (workbook instanceof HSSFWorkbook ? ".xls" : ".xlsx"), workbook);
+            bos = new ByteArrayOutputStream();
+            workbook.write(bos);
+            byte[] barray = bos.toByteArray();
+            com.lc.ibps.base.web.util.RequestUtil.downLoadFileByByte(this.getRequest(), this.getResponse(), barray, fileName);// 导出
+            apiResult.setMessage("导出成功");
+            apiResult.setState(StateEnum.SUCCESS.getCode());
+        } catch (Exception e) {
+            logger.error("/pv/exportExcelReport", e);
+            apiResult.setMessage("导出失败");
+            apiResult.setState(StateEnum.ERROR.getCode());
+        } finally {
+            if (bos != null) {
+                try {
+                    bos.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return apiResult;
+    }
+}

+ 161 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/CreateExcelScatterChart.java

@@ -0,0 +1,161 @@
+package com.lc.ibps.components.verification.excel;
+
+import com.lc.ibps.components.poi.excel.entity.params.ExcelExportEntity;
+import com.lc.ibps.components.verification.funcs.xValue;
+import com.lc.ibps.components.verification.model.InspectionItemVO;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.usermodel.charts.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.*;
+import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
+
+public class CreateExcelScatterChart {
+    public static void createLRE(Sheet sheet, InspectionItemVO item) {
+        ExcelExportEntity entity = new ExcelExportEntity("图表", "chart");
+        Row row = sheet.createRow(sheet.getLastRowNum() + 1);
+
+        for (int i = 0; i < item.getItemCalcVO().getTargetValue().length; i++) {
+            final xValue value = item.getItemCalcVO().getTargetValue()[i];
+            Cell cell = row.createCell(i);
+            cell.setCellValue(value.getDoub());
+            cell.setCellType(CellType.NUMERIC);
+        }
+        row.setZeroHeight(true);
+        int rowNum = row.getRowNum();
+
+        row = sheet.createRow(sheet.getLastRowNum() + 1);
+        for (int i = 0; i < item.getItemCalcVO().getSpecimensValue().length; i++) {
+            final xValue value = item.getItemCalcVO().getSpecimensValue()[i];
+            Cell cell = row.createCell(i);
+            cell.setCellValue(value.getDoub());
+            cell.setCellType(CellType.NUMERIC);
+        }
+        row.setZeroHeight(true);
+
+        row = sheet.createRow(sheet.getLastRowNum() + 1);
+        row.setHeight((short) (entity.getHeight() * 50));
+        Cell cell = row.createCell(0);
+        cell.setCellValue("线性回归图");
+        cell.setCellType(CellType.STRING);
+
+        Drawing<?> drawing = sheet.createDrawingPatriarch();
+        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, sheet.getLastRowNum() + 1, 6, sheet.getLastRowNum() + 9);
+
+        Chart chart = drawing.createChart(anchor);
+        ChartLegend legend = chart.getOrCreateLegend();
+        legend.setPosition(LegendPosition.TOP_RIGHT);
+
+        ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
+
+        ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
+        ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
+
+        leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
+        bottomAxis.setCrosses(AxisCrosses.AUTO_ZERO);
+        ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(rowNum, rowNum, 0, item.getConfig().getSpecimensNum()-1));
+        ChartDataSource<Number> ys = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(rowNum+1, rowNum+1, 0, item.getConfig().getSpecimensNum()-1));
+
+        ScatterChartSeries chartSeries = data.addSerie(xs, ys);
+        chartSeries.setTitle("线性回归");
+        chart.plot(data, bottomAxis, leftAxis);
+
+        final CTChart ctChart = ((XSSFChart) chart).getCTChart();
+//        ctChart.getLegend().getLegendPos().setVal(STLegendPos.B);
+        ctChart.unsetLegend();
+        ctChart.getPlotVisOnly().setVal(false);
+        //set line properties of first scatter chart data serie to no fill:
+        CTScatterSer[] scatterChartSeries = ctChart.getPlotArea().getScatterChartArray(0).getSerArray();
+        for (int i = 0; i < scatterChartSeries.length; i++) {
+            scatterChartSeries[i].addNewSpPr().addNewLn().addNewNoFill();
+        }
+//        ((XSSFChart) chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0).getDPtList().
+
+        for(CTValAx ax: ctChart.getPlotArea().getValAxList()){
+            ax.addNewMajorGridlines();
+        }
+        final CTTrendline trendline = ctChart.getPlotArea().getScatterChartArray(0).getSerArray(0)
+                .addNewTrendline();
+        trendline.addNewDispRSqr().setVal(true);
+        trendline.addNewIntercept().setVal(item.getItemCalcVO().getA().getDoub());
+        trendline.addNewDispEq().setVal(true);
+        trendline.addNewSpPr().addNewLn().addNewSolidFill().addNewSchemeClr().setVal(STSchemeColorVal.Enum.forInt(5));
+        trendline.addNewTrendlineType()
+                .setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STTrendlineType.LINEAR);
+
+        for (int i = 0; i < 8; i++) {
+
+            row = sheet.createRow(sheet.getLastRowNum() + 1);
+            row.setHeight((short) (entity.getHeight() * 50));
+        }
+    }
+
+    public static void createVarianceChart(Sheet sheet, InspectionItemVO item) {
+        ExcelExportEntity entity = new ExcelExportEntity("图表", "chart");
+        Row row = sheet.createRow(sheet.getLastRowNum() + 1);
+
+        for (int i = 0; i < item.getItemCalcVO().getTargetValue().length; i++) {
+            final xValue value = item.getItemCalcVO().getTargetValue()[i];
+            Cell cell = row.createCell(i);
+            cell.setCellValue(value.getDoub());
+            cell.setCellType(CellType.NUMERIC);
+        }
+        row.setZeroHeight(true);
+        int rowNum = row.getRowNum();
+
+        row = sheet.createRow(sheet.getLastRowNum() + 1);
+        for (int i = 0; i < item.getItemCalcVO().getSpecimensValue().length; i++) {
+            final xValue value = item.getItemCalcVO().getSpecimensValue()[i];
+            Cell cell = row.createCell(i);
+            cell.setCellValue(item.getRecord().get(item.getConfig().getSpecimensName()[i]).getRelDev().getDoub());
+            cell.setCellType(CellType.NUMERIC);
+        }
+        row.setZeroHeight(true);
+
+        row = sheet.createRow(sheet.getLastRowNum() + 1);
+        row.setHeight((short) (entity.getHeight() * 50));
+        Cell cell = row.createCell(0);
+        cell.setCellValue("差异图");
+        cell.setCellType(CellType.STRING);
+
+        Drawing<?> drawing = sheet.createDrawingPatriarch();
+        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, sheet.getLastRowNum() + 1, 6, sheet.getLastRowNum() + 9);
+
+        Chart chart = drawing.createChart(anchor);
+        ChartLegend legend = chart.getOrCreateLegend();
+        legend.setPosition(LegendPosition.TOP_RIGHT);
+
+        ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
+
+        ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
+        ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
+
+        leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
+        bottomAxis.setCrosses(AxisCrosses.AUTO_ZERO);
+        ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(rowNum, rowNum, 0, item.getConfig().getSpecimensNum()-1));
+        ChartDataSource<Number> ys = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(rowNum+1, rowNum+1, 0, item.getConfig().getSpecimensNum()-1));
+
+        ScatterChartSeries chartSeries = data.addSerie(xs, ys);
+        chartSeries.setTitle("差异图");
+        chart.plot(data, bottomAxis, leftAxis);
+
+        final CTChart ctChart = ((XSSFChart) chart).getCTChart();
+        ctChart.unsetLegend();
+        ctChart.getPlotVisOnly().setVal(false);
+        //set line properties of first scatter chart data serie to no fill:
+        CTScatterSer[] scatterChartSeries = ctChart.getPlotArea().getScatterChartArray(0).getSerArray();
+        for (int i = 0; i < scatterChartSeries.length; i++) {
+            scatterChartSeries[i].addNewSpPr().addNewLn().addNewNoFill();
+        }
+
+        for(CTValAx ax: ctChart.getPlotArea().getValAxList()){
+            ax.addNewMajorGridlines();
+        }
+
+        for (int i = 0; i < 8; i++) {
+
+            row = sheet.createRow(sheet.getLastRowNum() + 1);
+            row.setHeight((short) (entity.getHeight() * 50));
+        }
+    }
+}

+ 160 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelExportReportServer.java

@@ -0,0 +1,160 @@
+package com.lc.ibps.components.verification.excel;
+
+import com.lc.ibps.components.poi.excel.entity.params.ExcelExportEntity;
+import com.lc.ibps.components.poi.excel.export.ExcelExportServer;
+import com.lc.ibps.components.verification.model.FunctionEnum;
+import com.lc.ibps.components.verification.model.InspectionItemVO;
+import com.lc.ibps.components.verification.model.ItemCalcVO;
+import com.lc.ibps.components.verification.model.SpecimensCalcVO;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.util.Collection;
+
+public class PVExcelExportReportServer extends ExcelExportServer {
+    private InspectionItemVO item;
+
+    public void postHanderSheet(Sheet sheet, Collection<?> dataSet) {
+
+        boolean isChart = false;
+        ExcelExportEntity entity = new ExcelExportEntity("公式计算", "statistic");
+
+        Row row = sheet.createRow(sheet.getLastRowNum() + 1);
+        row.setHeight((short) (entity.getHeight() * 50));
+        for (FunctionEnum func : item.getConfig().getFunc()) {
+            row = sheet.createRow(sheet.getLastRowNum() + 1);
+            row.setHeight((short) (entity.getHeight() * 50));
+            int index = 0;
+            sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), index,
+                    index + 1));
+            entity.setKey("statistic");
+            createStringCell(row, index++, func.getText(), getStyles(false, entity), null);
+            createStringCell(row, index++, "", getStyles(false, entity), null);
+            if (func == FunctionEnum.LRE || func == FunctionEnum.R) {
+                createItemRow(sheet, entity, row, index, func);
+                isChart = true;
+            } else {
+                createSpecimensRow(sheet, entity, row, index, func);
+            }
+        }
+        createResultRow(sheet, entity, row);
+
+        if (isChart) CreateExcelScatterChart.createLRE(sheet, item);
+//        CreateExcelScatterChart.createVarianceChart(sheet, item);
+
+    }
+
+    private void createResultRow(Sheet sheet, ExcelExportEntity entity, Row row) {
+        int index = item.getConfig().getSpecimensNum() + 2;
+        if (item.getConfig().isConvert()) {
+            index = item.getConfig().getSpecimensNum() * 2 + 2;
+        }
+        entity.setKey("statistic");
+        sheet.addMergedRegion(new CellRangeAddress(row.getRowNum() + 1, row.getRowNum() + 3, 0,
+                1));
+        sheet.addMergedRegion(new CellRangeAddress(row.getRowNum() + 1, row.getRowNum() + 3, 2,
+                index - 1));
+        for (int i = 0; i < 3; i++) {
+            row = sheet.createRow(sheet.getLastRowNum() + 1);
+            row.setHeight((short) (entity.getHeight() * 50));
+            createStringCell(row, 0, "结果分析", getStyles(false, entity), null);
+            createStringCell(row, 1, "", getStyles(false, entity), null);
+            createStringCell(row, 2, "PASS", getStyles(false, entity), null);
+            for (int j = 3; j < index; j++) createStringCell(row, j, "", getStyles(false, entity), null);
+        }
+    }
+
+    private void createItemRow(Sheet sheet, ExcelExportEntity entity, Row row, int index, FunctionEnum func) {
+        int i = 0;
+        if (item.getConfig().isConvert()) {
+            i = index - 1 + item.getConfig().getSpecimensNum() * 2;
+            sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), index, i));
+        } else {
+            i = index - 1 + item.getConfig().getSpecimensNum();
+            sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), index, i));
+        }
+        entity.setKey(getCellStyle(func));
+        if (func == FunctionEnum.R) {
+            createDoubleCell(row, index++, getCalcValue(func, item.getItemCalcVO()), getStyles(false, entity), null);
+        } else {
+            createStringCell(row, index++, getCalcValue(func, item.getItemCalcVO()), getStyles(false, entity), null);
+        }
+        for (int j = index; j <= i; j++) {
+            createStringCell(row, index++, "0", getStyles(false, entity), null);
+        }
+    }
+
+    private void createSpecimensRow(Sheet sheet, ExcelExportEntity entity, Row row, int index, FunctionEnum func) {
+
+        for (int i = 0; i < item.getConfig().getSpecimensNum(); i++) {
+            String s = item.getConfig().getSpecimensName()[i];
+            SpecimensCalcVO specimensCalcVO = item.getRecord().get(s);
+            if (item.getConfig().isConvert()) {
+                sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), index,
+                        index + 1));
+            }
+            entity.setKey(getCellStyle(func));
+            createStringCell(row, index++, getCalcValue(func, specimensCalcVO), getStyles(false, entity), null);
+            if (item.getConfig().isConvert()) {
+                createStringCell(row, index++, "0", getStyles(false, entity), null);
+            }
+
+        }
+    }
+
+    public String getCalcValue(FunctionEnum func, SpecimensCalcVO specimensCalcVO) {
+        switch (func) {
+            case CV:
+                return specimensCalcVO.getCv().getStr();
+            case SD:
+                return specimensCalcVO.getSd().getStr();
+            case AVERAGE:
+                return specimensCalcVO.getAverage().getStr();
+            case TARGET:
+                return specimensCalcVO.getTargetValue().toString();
+            case ABSDEV:
+                return specimensCalcVO.getAbsDev().getStr();
+            case RVALUE:
+                return specimensCalcVO.getRvalue().getStr();
+            case RELDEV:
+                return specimensCalcVO.getRelDev().getStr();
+            default:
+                return "";
+        }
+    }
+
+    public String getCalcValue(FunctionEnum func, ItemCalcVO itemCalcVO) {
+        switch (func) {
+            case R:
+                return itemCalcVO.getR().getStr();
+            case LRE:
+                return itemCalcVO.getLRE();
+            default:
+                return "";
+        }
+    }
+
+    public String getCellStyle(FunctionEnum func) {
+        switch (func) {
+            case RVALUE:
+            case CV:
+                return "statistic-percent";
+            case R:
+                return "statistic-double4";
+            case LRE:
+                return "statistic";
+            default:
+                return "statistic-double";
+        }
+    }
+
+
+    public InspectionItemVO getItem() {
+        return item;
+    }
+
+    public void setItem(InspectionItemVO item) {
+        this.item = item;
+    }
+}

+ 101 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelExportStyler.java

@@ -0,0 +1,101 @@
+package com.lc.ibps.components.verification.excel;
+
+import com.lc.ibps.components.poi.excel.entity.params.ExcelExportEntity;
+import com.lc.ibps.components.poi.excel.export.styler.ExcelExportStylerBorderImpl;
+import org.apache.poi.ss.usermodel.*;
+
+public class PVExcelExportStyler extends ExcelExportStylerBorderImpl {
+
+    protected CellStyle inputNumberStyle;
+    protected CellStyle scientificNotationNumberStyle;
+    protected CellStyle doubleNumberStyle;
+    protected CellStyle statisticNumberStyle;
+
+    protected CellStyle statisticDoubleNumberStyle;
+
+    protected  CellStyle statisticPercentNumberStyle;
+    protected  CellStyle statisticDouble4NumberStyle;
+
+    public PVExcelExportStyler(Workbook workbook) {
+        super(workbook);
+        inputNumberStyle = inputNumberStyle(workbook);
+        scientificNotationNumberStyle = scientificNotationNumberStyle(workbook);
+        doubleNumberStyle = doubleNumberStyle(workbook);
+        statisticNumberStyle = statisticNumberStyle(workbook);
+        statisticDoubleNumberStyle = statisticDoubleNumberStyle(workbook);
+        statisticPercentNumberStyle = statisticPercentNumberStyle(workbook);
+        statisticDouble4NumberStyle = statisticDouble4NumberStyle(workbook);
+    }
+
+
+
+    public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity) {
+        if(entity != null  ) {
+            if("input".equals(entity.getKey()))   return inputNumberStyle;
+            if("value".equals(entity.getKey())) return scientificNotationNumberStyle;
+            if("log".equals(entity.getKey())) return doubleNumberStyle;
+            if("statistic".equals(entity.getKey())) return statisticNumberStyle;
+            if("statistic-double".equals(entity.getKey())) return statisticDoubleNumberStyle;
+            if("statistic-double4".equals(entity.getKey())) {return statisticDouble4NumberStyle;}
+            if("statistic-percent".equals(entity.getKey())) return statisticPercentNumberStyle;
+        }
+        return super.getStyles(noneStyler, entity);
+    }
+
+    public CellStyle inputNumberStyle(Workbook workbook) {
+        CellStyle style = createCellStyle(workbook);
+        style.setDataFormat((short) BuiltinFormats.getBuiltinFormat("General"));
+        style.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        return style;
+    }
+
+    public CellStyle scientificNotationNumberStyle(Workbook workbook) {
+        CellStyle style = createCellStyle(workbook);
+        style.setDataFormat((short) BuiltinFormats.getBuiltinFormat("0.00E+00"));
+        return style;
+    }
+
+    public CellStyle doubleNumberStyle(Workbook workbook) {
+        CellStyle style = createCellStyle(workbook);
+        style.setDataFormat((short) BuiltinFormats.getBuiltinFormat("0.00"));
+        return style;
+    }
+
+    private CellStyle statisticNumberStyle(Workbook workbook) {
+        CellStyle style = createCellStyle(workbook);
+        style.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        return style;
+    }
+
+    private CellStyle statisticPercentNumberStyle(Workbook workbook) {
+        CellStyle style = statisticNumberStyle(workbook);
+        style.setDataFormat((short) BuiltinFormats.getBuiltinFormat("0.00%"));
+        return style;
+    }
+
+    private CellStyle statisticDoubleNumberStyle(Workbook workbook) {
+        CellStyle style = statisticNumberStyle(workbook);
+        style.setDataFormat((short) BuiltinFormats.getBuiltinFormat("0.00"));
+        return style;
+    }
+
+    private CellStyle statisticDouble4NumberStyle(Workbook workbook) {
+        CellStyle style = statisticNumberStyle(workbook);
+        style.setDataFormat(workbook.createDataFormat().getFormat("0.0000"));
+        return style;
+    }
+
+    private  CellStyle createCellStyle(Workbook workbook){
+        CellStyle style = workbook.createCellStyle();
+        style.setBorderLeft(BorderStyle.THIN); // 左边框
+        style.setBorderRight(BorderStyle.THIN); // 右边框
+        style.setBorderBottom(BorderStyle.THIN);
+        style.setBorderTop(BorderStyle.THIN);
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setDataFormat(STRING_FORMAT);
+        return style;
+    }
+}

+ 44 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelExportTemplateServer.java

@@ -0,0 +1,44 @@
+package com.lc.ibps.components.verification.excel;
+
+import com.lc.ibps.components.poi.excel.entity.ExportParams;
+import com.lc.ibps.components.poi.excel.entity.params.ExcelExportEntity;
+import com.lc.ibps.components.poi.excel.export.ExcelExportServer;
+import org.apache.poi.ss.usermodel.CellStyle;
+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.util.CellRangeAddress;
+
+import java.util.List;
+
+public class PVExcelExportTemplateServer extends ExcelExportServer {
+    protected int createHeaderAndTitle(ExportParams entity, Sheet sheet, Workbook workbook,
+                                       List<ExcelExportEntity> excelParams) {
+        int rows = 0, feildWidth = getFieldLength(excelParams);
+        if (entity.getTitle() != null) {
+            rows += createHeaderRow(entity, sheet, workbook, feildWidth);
+        }
+        rows += createInspectionDateRow(entity, sheet, rows,workbook, feildWidth);
+        rows += createTitleRow(entity, sheet, workbook, rows, excelParams);
+        sheet.createFreezePane(0, rows, 0, rows);
+        return rows;
+    }
+
+    private int createInspectionDateRow(ExportParams title, Sheet sheet,int index, Workbook workbook,int feildWidth) {
+
+        Row row = sheet.createRow(index);
+        row.setHeight((short) 450);
+        CellStyle titleStyle = getExcelExportStyler().getTitleStyle(title.getColor());
+        createStringCell(row, 0, "实验日期", titleStyle, null);
+        createStringCell(row, 1, title.getSheetName(), titleStyle, null);
+        createStringCell(row, feildWidth, "", titleStyle, null);
+        CellRangeAddress region = new CellRangeAddress(index, index, 1, feildWidth);
+
+        sheet.addMergedRegion(region);
+
+        return 1;
+    }
+
+
+
+}

+ 114 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelImportServer.java

@@ -0,0 +1,114 @@
+package com.lc.ibps.components.verification.excel;
+
+import com.lc.ibps.components.poi.excel.entity.ImportParams;
+import com.lc.ibps.components.poi.excel.entity.params.ExcelCollectionParams;
+import com.lc.ibps.components.poi.excel.entity.result.ExcelImportResult;
+import com.lc.ibps.components.poi.excel.imports.ExcelImportServer;
+import com.lc.ibps.components.verification.model.ExcelSheetRecord;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.util.*;
+
+public class PVExcelImportServer extends ExcelImportServer {
+    private static final Logger LOGGER = LoggerFactory.getLogger(PVExcelImportServer.class);
+    public ExcelImportResult importExcelByIs(InputStream inputstream, Class<?> pojoClass, ImportParams params)
+            throws Exception {
+        if (LOGGER.isInfoEnabled()) {
+            LOGGER.info("Excel import start ,class is {}", pojoClass);
+        }
+        List<ExcelSheetRecord> result = new ArrayList<ExcelSheetRecord>();
+        Workbook book = null;
+        boolean isXSSFWorkbook = true;
+        if (!(inputstream.markSupported())) {
+            inputstream = new PushbackInputStream(inputstream, 8);
+        }
+        try{
+            if (POIFSFileSystem.hasPOIFSHeader(inputstream)) {
+                book = new HSSFWorkbook(inputstream);
+                isXSSFWorkbook = false;
+            } else if (DocumentFactoryHelper.hasOOXMLHeader(inputstream)) {
+                book = new XSSFWorkbook(OPCPackage.open(inputstream));
+            }
+        }catch (Exception e){
+            book=null;
+        }
+        if(book==null){
+            try{
+                book = new HSSFWorkbook(inputstream);
+                isXSSFWorkbook = false;
+            }catch (Exception e){
+                e.printStackTrace();
+                book = new XSSFWorkbook(OPCPackage.open(inputstream));
+                isXSSFWorkbook = true;
+            }
+        }
+        createErrorCellStyle(book);
+        for (int i = params.getStartSheetIndex(); i < params.getStartSheetIndex() + params.getSheetNum(); i++) {
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info(" start to read excel by is ,startTime is {}", new Date().getTime());
+            }
+
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info(" end to read excel by is ,endTime is {}", new Date().getTime());
+            }
+            List list = importExcel(result, book.getSheetAt(i), pojoClass, params, null);
+            result.add(new ExcelSheetRecord(book.getSheetAt(i).getSheetName(),list));
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info(" end to read excel list by pos ,endTime is {}", new Date().getTime());
+            }
+        }
+        if (params.isNeedSave()) {
+            saveThisExcel(params, pojoClass, isXSSFWorkbook, book);
+        }
+        return new ExcelImportResult(result, verfiyFail, book);
+    }
+    protected Map<Integer, String> getTitleMap(Iterator<Row> rows, ImportParams params,
+                                               List<ExcelCollectionParams> excelCollection) {
+        Map<Integer, String> titlemap = new HashMap<Integer, String>();
+        Iterator<Cell> cellTitle;
+        String collectionName = null;
+        ExcelCollectionParams collectionParams = null;
+        Row row = null;
+        for (int j = 0; j < params.getHeadRows(); j++) {
+            row = rows.next();
+            if (row == null) {
+                continue;
+            }
+            cellTitle = row.cellIterator();
+            while (cellTitle.hasNext()) {
+                Cell cell = cellTitle.next();
+                String value = getKeyValue(cell);
+                value = value.replace("\n", "");
+                int i = cell.getColumnIndex();
+                // 用以支持重名导入
+                if (StringUtils.isNotEmpty(value)) {
+                    if (titlemap.containsKey(i)) {
+                        collectionName = titlemap.get(i);
+                        titlemap.put(i, collectionName + "_" + value);
+                    } else if (StringUtils.isNotEmpty(collectionName) ) {
+                        titlemap.put(i, collectionName + "_" + value);
+                    } else {
+                        collectionName = null;
+                    }
+                    if (StringUtils.isEmpty(collectionName)) {
+                        titlemap.put(i, value);
+                    }
+                }
+            }
+        }
+        return titlemap;
+    }
+
+}

+ 184 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVExcelUtil.java

@@ -0,0 +1,184 @@
+package com.lc.ibps.components.verification.excel;
+
+import com.lc.ibps.components.poi.excel.entity.ExportParams;
+import com.lc.ibps.components.poi.excel.entity.ImportParams;
+import com.lc.ibps.components.poi.excel.entity.enmus.ExcelType;
+import com.lc.ibps.components.poi.excel.entity.params.ExcelExportEntity;
+import com.lc.ibps.components.poi.excel.entity.result.ExcelImportResult;
+import com.lc.ibps.components.poi.excel.export.ExcelExportServer;
+import com.lc.ibps.components.poi.exception.excel.ExcelImportException;
+import com.lc.ibps.components.verification.model.InspectionItemVO;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class PVExcelUtil {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(PVExcelUtil.class);
+
+    /**
+     * 根据Map创建对应的Excel
+     *
+     * @param entity     表格标题属性
+     * @param entityList Map对象列表
+     * @param dataSet    Excel对象数据List
+     */
+    public static Workbook exportExcel(ExportParams entity, List<ExcelExportEntity> entityList,
+                                       Collection<? extends Map<?, ?>> dataSet) {
+        Workbook workbook;
+        if (ExcelType.HSSF.equals(entity.getType())) {
+            workbook = new HSSFWorkbook();
+        } else if (dataSet.size() < 10000) {
+            workbook = new XSSFWorkbook();
+        } else {
+            workbook = new SXSSFWorkbook();
+        }
+        new PVExcelExportTemplateServer().createSheetForMap(workbook, entity, entityList, dataSet);
+        return workbook;
+    }
+
+    public static Workbook exportExcelReport(List<Map<String, Object>> list, ExcelType type) {
+        Workbook workbook;
+        if (ExcelType.HSSF.equals(type)) {
+            workbook = new HSSFWorkbook();
+        } else {
+            workbook = new XSSFWorkbook();
+        }
+        for (Map<String, Object> map : list) {
+            PVExcelExportReportServer server = new PVExcelExportReportServer();
+            server.setItem((InspectionItemVO) map.get("item"));
+            server.createSheetForMap(workbook, (ExportParams) map.get("params"),
+                    (List<ExcelExportEntity>) map.get("entity"), (Collection<?>) map.get("data"));
+
+
+        }
+        return workbook;
+    }
+
+    /**
+     * 一个excel 创建多个sheet
+     *
+     * @param list 多个Map key title 对应表格Title key entity 对应表格对应实体 key data
+     *             Collection 数据
+     * @return
+     */
+    public static Workbook exportExcelTemplateWithMultiSheet(
+            List<ExportParams> entities, List<ExcelExportEntity> entityList,
+            Collection<? extends Map<?, ?>> dataSet) {
+        Workbook workbook;
+        if (ExcelType.HSSF.equals(entities.get(0).getType())) {
+            workbook = new HSSFWorkbook();
+        } else if (dataSet.size() < 10000) {
+            workbook = new XSSFWorkbook();
+        } else {
+            workbook = new SXSSFWorkbook();
+        }
+        for (ExportParams entity : entities) {
+            new PVExcelExportTemplateServer().createSheetForMap(
+                    workbook, entity, entityList, new ArrayList<>(dataSet));
+        }
+
+        return workbook;
+    }
+
+
+    /**
+     * Excel 导入 数据源本地文件,不返回校验结果 导入 字 段类型 Integer,Long,Double,Date,String,Boolean
+     *
+     * @param file
+     * @param pojoClass
+     * @param params
+     * @return
+     */
+    public static <T> List<T> importExcel(InputStream inputstream, Class<?> pojoClass, ImportParams params) {
+        FileInputStream in = null;
+        try {
+            ExcelImportResult result = new PVExcelImportServer().importExcelByIs(inputstream, pojoClass, params);
+
+            return result.getList();
+        } catch (ExcelImportException e) {
+            throw new ExcelImportException(e.getType(), e);
+        } catch (Exception e) {
+            LOGGER.error(e.getMessage(), e);
+            throw new ExcelImportException(e.getMessage(), e);
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+
+    public static String getCellValueByCell(Sheet sheet, int row, int column) {
+        Row rowData = sheet.getRow(row);
+        Cell cell = rowData.getCell(column);
+        //判断是否为null或空串
+        if (cell == null || cell.toString().trim().equals("")) {
+            return "";
+        }
+        String cellValue = "";
+        int cellType = cell.getCellType();
+        switch (cellType) {
+            case Cell.CELL_TYPE_NUMERIC: // 数字
+                short format = cell.getCellStyle().getDataFormat();
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    SimpleDateFormat sdf = null;
+                    //System.out.println("cell.getCellStyle().getDataFormat()="+cell.getCellStyle().getDataFormat());
+                    if (format == 20 || format == 32) {
+                        sdf = new SimpleDateFormat("HH:mm");
+                    } else if (format == 14 || format == 31 || format == 57 || format == 58) {
+                        // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
+                        sdf = new SimpleDateFormat("yyyy-MM-dd");
+                        double value = cell.getNumericCellValue();
+                        Date date = org.apache.poi.ss.usermodel.DateUtil
+                                .getJavaDate(value);
+                        cellValue = sdf.format(date);
+                    } else {// 日期
+                        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                    }
+                    try {
+                        cellValue = sdf.format(cell.getDateCellValue());// 日期
+                    } catch (Exception e) {
+                        try {
+                            throw new Exception("exception on get date data !".concat(e.toString()));
+                        } catch (Exception e1) {
+                            e1.printStackTrace();
+                        }
+                    } finally {
+                        sdf = null;
+                    }
+                } else {
+                    BigDecimal bd = new BigDecimal(cell.getNumericCellValue());
+                    cellValue = bd.toPlainString();// 数值 这种用BigDecimal包装再获取plainString,可以防止获取到科学计数值
+                }
+                break;
+            case Cell.CELL_TYPE_STRING: // 字符串
+                cellValue = cell.getStringCellValue();
+                break;
+            case Cell.CELL_TYPE_BOOLEAN: // Boolean
+                cellValue = cell.getBooleanCellValue() + "";
+                ;
+                break;
+            case Cell.CELL_TYPE_FORMULA: // 公式
+                cellValue = cell.getCellFormula();
+                break;
+            case Cell.CELL_TYPE_BLANK: // 空值
+                cellValue = "";
+                break;
+            case Cell.CELL_TYPE_ERROR: // 故障
+                cellValue = "ERROR VALUE";
+                break;
+            default:
+                cellValue = "UNKNOW VALUE";
+                break;
+        }
+        return cellValue;
+    }
+}

+ 135 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/excel/PVTest.java

@@ -0,0 +1,135 @@
+package com.lc.ibps.components.verification.excel;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.lc.ibps.components.verification.model.FunctionEnum;
+import com.lc.ibps.components.verification.model.InspectionConfigVO;
+import com.lc.ibps.components.verification.model.InspectionItemVO;
+import com.lc.ibps.components.verification.model.InspectionVO;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.apache.poi.xssf.usermodel.XSSFDrawing;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.junit.Test;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
+
+import java.io.*;
+import java.time.LocalDate;
+import java.util.*;
+
+public class PVTest {
+
+    @Test
+    public void testExcelImport() throws FileNotFoundException {
+
+        InspectionConfigVO config = new InspectionConfigVO("批内精密度", 1, 2,
+                new String[]{"高溶度(R1)", "低浓度(R2)"}, 10, LocalDate.now(), true);
+
+        File file = new File(String.format("C:/tmp/%s.xlsx", config.getName()));
+        FileInputStream in = new FileInputStream(file);
+
+        InspectionItemVO item = new InspectionItemVO(config);
+        item.importExcelRecord(in);
+
+        System.out.println(item);
+//        for(Map<String, Object> d : list)
+//            System.out.println(d);
+
+    }
+
+    @Test
+    public void testExcelTemplateExport() throws IOException {
+//        InspectionConfigVO config = new InspectionConfigVO("批内精密度",1,2,
+//                new String[]{"高溶度(R1)","低浓度(R2)"},10, LocalDate.now(),true);
+
+//        InspectionConfigVO config = new InspectionConfigVO("正确度",5,2,
+//                new String[]{"L2","L4"},2, LocalDate.now(),true);
+
+        InspectionConfigVO config = new InspectionConfigVO("线性范围", 1, 7,
+                new String[]{"E8", "E7", "E6", "E5", "E4", "E3", "E2"}, 3, LocalDate.now(), true);
+
+        InspectionItemVO item = new InspectionItemVO(config);
+        Workbook workbook = item.exportExcelTemplate();
+        FileOutputStream fos = new FileOutputStream(String.format("C:/tmp/%s.xlsx", config.getName()));
+        workbook.write(fos);
+        fos.close();
+    }
+
+    @Test
+    public void testExcelReportExport() throws IOException {
+
+        //批间精密度
+//        InspectionConfigVO config = new InspectionConfigVO("批间精密度",5,2,
+//                new String[]{"高溶度(R1)","低浓度(R2)"},3, LocalDate.now(),true);
+//        config.setFunc(new FunctionEnum[]{FunctionEnum.AVERAGE,FunctionEnum.SD,FunctionEnum.CV});
+//        InspectionItemVO item = new InspectionItemVO(config);
+//        File file = new File(String.format("C:/tmp/%sdata.xlsx",config.getName()));
+//        FileInputStream in = new FileInputStream(file);
+//        item.importExcelRecord(in);
+        //批内精密度
+//        InspectionConfigVO config2 = new InspectionConfigVO("批内精密度",1,2,
+//                new String[]{"高溶度(R1)","低浓度(R2)"},10, LocalDate.now(),true);
+//        config2.setFunc(new FunctionEnum[]{FunctionEnum.AVERAGE,FunctionEnum.SD,FunctionEnum.CV});
+//        InspectionItemVO item2 = new InspectionItemVO(config2);
+//        File file2 = new File(String.format("C:/tmp/%sdata.xlsx",config2.getName()));
+//        FileInputStream in2 = new FileInputStream(file2);
+//        item2.importExcelRecord(in2);
+
+        //正确度
+//        InspectionConfigVO config3 = new InspectionConfigVO("正确度",5,2,
+//                new String[]{"L2","L4"},2, LocalDate.now(),true);
+//        config3.setFunc(new FunctionEnum[]{FunctionEnum.AVERAGE,FunctionEnum.TARGET,FunctionEnum.ABSDEV});
+//        config3.setTargetValue(new double[]{6.32,4.32});
+//        InspectionItemVO item3 = new InspectionItemVO(config3);
+//        File file3 = new File(String.format("C:/tmp/%sdata.xlsx",config3.getName()));
+//        FileInputStream in3 = new FileInputStream(file3);
+//        item3.importExcelRecord(in3);
+
+        //线性范围
+        InspectionConfigVO config4 = new InspectionConfigVO("线性范围", 1, 7,
+                new String[]{"E8", "E7", "E6", "E5", "E4", "E3", "E2"}, 3, LocalDate.now(), true);
+
+        config4.setFunc(new FunctionEnum[]{FunctionEnum.AVERAGE,FunctionEnum.TARGET,FunctionEnum.LRE, FunctionEnum.R});
+        config4.setTargetValue(new double[]{8.48, 7.48, 6.48, 5.48, 4.58, 3.58, 2.58});
+        InspectionItemVO item4 = new InspectionItemVO(config4);
+        File file4 = new File(String.format("C:/tmp/%sdata.xlsx", config4.getName()));
+        FileInputStream in4 = new FileInputStream(file4);
+        item4.importExcelRecord(in4);
+
+
+        InspectionVO vo = new InspectionVO();
+        vo.setName("TEST");
+//        vo.getItem().add(item);
+//        vo.getItem().add(item2);
+//        vo.getItem().add(item3);
+        vo.getItem().add(item4);
+        final String s = JSONObject.toJSONString(vo,SerializerFeature.PrettyFormat,SerializerFeature.DisableCircularReferenceDetect);
+        InspectionVO voJson = JSON.parseObject(s, InspectionVO.class);
+
+        System.out.println(s);
+        final Workbook workbook = vo.exportExcelReport(false);
+        FileOutputStream fos = new FileOutputStream(String.format("C:/tmp/%s.xlsx", vo.getName()));
+        workbook.write(fos);
+        fos.close();
+
+
+    }
+
+    @Test
+    public void testChart() throws Exception {
+        FileInputStream fis = new FileInputStream("C:/tmp/TEST.xlsx");
+        XSSFWorkbook wb = new XSSFWorkbook(fis);
+        XSSFSheet sheet = wb.getSheetAt(0);
+        XSSFDrawing drawing = sheet.getDrawingPatriarch();
+        List<XSSFChart> charts = drawing.getCharts();
+        for (int i = 0; i < charts.size(); i++) {
+            XSSFChart chart = charts.get(i);
+            CTChart ctChart = chart.getCTChart();
+            System.out.println(ctChart);
+        }
+        fis.close();
+        wb.close();
+    }
+}

+ 38 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/TestFuncs.java

@@ -0,0 +1,38 @@
+package com.lc.ibps.components.verification.funcs;
+
+import org.junit.Test;
+
+public class TestFuncs {
+    @Test
+    public  void test(){
+        double[] cNode11 = {25.30 ,28.40 ,32.50 ,36.90 ,42.70 ,49.80 ,55.10 ,62.30 ,65.40 ,69.70 ,85.40 ,89.60 ,91.30 ,99.40 ,105.60 ,135.40 ,162.40 ,173.40 ,184.50 ,192.60 ,203.60 ,219.80 ,235.60 ,233.70 ,216.90 ,265.80 ,272.60 ,288.80 ,294.60 ,309.40 ,335.60 ,356.40 ,342.90 ,365.70 ,385.40 ,376.30 ,402.00 ,415.00 ,426.90 ,468.0};
+        double[] cNode21 = {26.40 ,29.30 ,33.50 ,35.90 ,43.10 ,50.90 ,56.80 ,63.40 ,62.70 ,72.40 ,88.10 ,90.30 ,90.60 ,98.40 ,102.70 ,130.60 ,165.90 ,170.60 ,186.50 ,199.40 ,203.50 ,220.70 ,234.90 ,236.70 ,210.90 ,270.10 ,276.40 ,290.00 ,298.00 ,310.00 ,339.00 ,354.00 ,343.00 ,369.00 ,387.00 ,372.00 ,404.00 ,416.00 ,429.00 ,470.00};
+        xValue[] cNode1 = convert(cNode11);
+        xValue[] cNode2 = convert(cNode21);
+        xValue xValue = xAverage.eval(cNode1);
+        System.out.println(xValue.getDoub());
+        xValue[] x = xLog10.eval(cNode1);
+        System.out.println(x);
+        xValue xValue1 = xFuncStdevVar.evalArgs((cNode1), xFuncStdevVar.iSTDEV);
+        xValue xValue2 = xFuncStdevVar.evalArgs((cNode2), xFuncStdevVar.iSTDEV);
+        System.out.println(xValue1.getDoub());
+        System.out.println(xValue2.getDoub());
+
+        xValue b = xFuncArray2Args.evalArgs(cNode2,cNode1,  xFuncArray2Args.iSLOPE);
+        System.out.println(b.getDoub());
+
+        xValue a = xFuncArray2Args.evalArgs(cNode2,cNode1,  xFuncArray2Args.iINTERCEPT);
+        System.out.println(a.getDoub());
+
+        xValue r = xFuncArray2Args.evalArgs(cNode2,cNode1,  xFuncArray2Args.iCORREL);
+        System.out.println(r.getDoub());
+    }
+
+    public static xValue[] convert(double[] data){
+        xValue[] c = new xValue[data.length];
+        for (int i = 0; i < data.length; i++) {
+            c[i] = new xValue(data[i]);
+        }
+        return c;
+    }
+}

+ 29 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xAverage.java

@@ -0,0 +1,29 @@
+package com.lc.ibps.components.verification.funcs;
+
+public class xAverage {
+
+
+    /** AVERAGEs n ranges. */
+    public static xValue eval(xValue[] cNod) {
+        xValue valRes = new xValue();
+        try {
+            int iCnt = 0;
+            double dSum = 0;
+            xValue val ;
+            for (int ii = cNod.length; --ii >= 0; ) {
+                val = cNod[ii];
+                dSum += val.getDoub();
+                iCnt++;
+
+            }
+            if (iCnt == 0) {
+                valRes.setErrDiv();
+            } else {
+                valRes.setVal(dSum / iCnt);
+            }
+        } catch (Exception e) {
+            valRes.setErrVal();
+        }
+        return valRes;
+    }
+}

+ 121 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xFuncArray2Args.java

@@ -0,0 +1,121 @@
+package com.lc.ibps.components.verification.funcs;
+
+import java.io.Serializable;
+
+public class xFuncArray2Args implements Serializable {
+    public static int iCOVAR = 0;
+    public static int iCORREL = 1;
+    public static int iINTERCEPT = 2;
+    public static int iPEARSON = 3;
+    public static int iRSQ = 4;
+    public static int iSLOPE = 5;
+    public static int iSTEYX = 6;
+
+    /**
+     * Generic function that helps calculate a function with 2 array arguments,
+     * like COVAR, CORREL, etc.
+     * @param cNod    the result node
+     * @param iFunc   the calling function (0=COVAR, etc)
+     * @return        true if the node has been evaluated successfully
+     */
+    //We may want redo this method in the future in order to make it clearer.
+    public static xValue evalArgs(xValue[] cNod1, xValue[] cNod2, int iFunc) {
+        xValue valRes = new xValue();
+
+
+        if (cNod1.length == cNod2.length) {
+            int iCnt = cNod1.length;
+            double[][] dblSets = new double[iCnt][2];
+            boolean[] boolSets = new boolean[iCnt];
+
+            //Here we capture both arrays in a single array 'dblSets'
+            //which will contain essentially an array of sets of doubles
+            //'boolSets' keeps track of non-doubles
+            for (int ii = 0; ii < iCnt; ii++) {
+                boolSets[ii] = true;
+                dblSets[ii][0] = cNod1[ii].getDoub();
+                dblSets[ii][1] = cNod2[ii].getDoub();
+            }
+
+            //Here we calculate generic intermediate results
+            int nn = 0;
+
+            double xx = 0;
+            double yy = 0;
+            double xy = 0;
+            double xx2 = 0;
+            double yy2 = 0;
+            boolean bEmpty = true;
+            for (int ii = 0; ii < iCnt; ii++) {
+                if (boolSets[ii]) {
+                    bEmpty = false;
+                    nn++;
+                    xx = xx + dblSets[ii][0];
+                    yy = yy + dblSets[ii][1];
+                    xy = xy + dblSets[ii][0] * dblSets[ii][1];
+                    xx2 = xx2 + dblSets[ii][0] * dblSets[ii][0];
+                    yy2 = yy2 + dblSets[ii][1] * dblSets[ii][1];
+                }
+            }
+
+            //Here is where we actually perform an operation on the arrays,
+            //depending on the calling function
+            if (bEmpty && ((iFunc == iCOVAR) || (iFunc == iCORREL))) {
+                valRes.setErrDiv();
+            } else if (bEmpty) {
+                valRes.setErrNa();
+            } else if (iFunc == iINTERCEPT || (iFunc == iSLOPE)) {
+                double denom = nn * yy2 - yy * yy;
+                if (denom == 0) {
+                    valRes.setErrDiv();
+                } else if (iFunc == iINTERCEPT) {
+                    valRes.setVal(xx / nn - yy / nn * (nn * xy - xx * yy) / denom);
+                } else if (iFunc == iSLOPE) {
+                    valRes.setVal((nn * xy - xx * yy) / denom);
+                }
+            } else if (iFunc == iPEARSON || (iFunc == iRSQ)) {
+                double denom = Math.pow((nn * xx2 - xx * xx) * (nn * yy2 - yy * yy), 0.5);
+                if (denom == 0) {
+                    valRes.setErrDiv();
+                } else if (iFunc == iPEARSON) {
+                    valRes.setVal((nn * xy - xx * yy) / denom);
+                } else if (iFunc == iRSQ) {
+                    valRes.setVal(Math.pow((nn * xy - xx * yy) / denom, 2));
+                }
+            } else if (iFunc == iSTEYX) {
+                double denom1 = nn * (nn - 2);
+                double denom2 = nn * yy2 - yy * yy;
+                if ((denom1 == 0) || (denom2 == 0)) {
+                    valRes.setErrDiv();
+                } else {
+                    valRes.setVal(Math.pow(1.0 / denom1 * (nn * xx2 - xx * xx - Math.pow(nn * xy - yy * xx, 2) / denom2), 0.5));
+                }
+            } else if ((iFunc == iCOVAR) || (iFunc == iCORREL)) {
+                double dAvgx = xx / nn;
+                double dAvgy = yy / nn;
+                double dCovar = 0;
+                for (int ii = 0; ii < iCnt; ii++) {
+                    if (boolSets[ii]) {
+                        dCovar = dCovar + (dblSets[ii][0] - dAvgx) * (dblSets[ii][1] - dAvgy);
+                    }
+                }
+                if (iFunc == iCOVAR) {
+                    valRes.setVal(dCovar / nn);
+                } else if (iFunc == iCORREL) {
+                    double dStdevX = Math.pow((nn * xx2 - Math.pow(xx, 2.0)) / (nn * nn), 0.5);
+                    double dStdevY = Math.pow((nn * yy2 - Math.pow(yy, 2.0)) / (nn * nn), 0.5);
+                    if ((dStdevX == 0) || (dStdevY == 0)) {
+                        valRes.setErrDiv();
+                    } else {
+                        valRes.setVal((dCovar / nn) / (dStdevX * dStdevY));
+                    }
+                }
+            }
+        } else {
+            valRes.setErrNa();
+        }
+
+        return valRes;
+    }
+}
+

+ 50 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xFuncStdevVar.java

@@ -0,0 +1,50 @@
+package com.lc.ibps.components.verification.funcs;
+
+import java.io.Serializable;
+
+public class xFuncStdevVar implements Serializable {
+    public static int iSTDEV = 0;
+    public static int iSTDEVA = 1;
+    public static int iSTDEVP = 2;
+    public static int iSTDEVPA = 3;
+    public static int iVAR = 4;
+    public static int iVARA = 5;
+    public static int iVARP = 6;
+    public static int iVARPA = 7;
+
+    /**
+     * Generic function that helps calculate a function with 1+ arguments,
+     * The arguments could be 1 or more.
+     * @param cNod    the result node
+     * @param iFunc   the calling function (0=STDEV, etc)
+     * @return        true if the node has been evaluated successfully
+     */
+    //We may want redo this method in the future in order to make it clearer.
+    public static xValue evalArgs(xValue[] cNod, int iFunc) {
+        xValue valRes = new xValue();
+
+        double dBuff = 0;
+        double xx = 0;
+        double xx2 = 0;
+        long nn = 0;
+        for (int ii = 0; ii < cNod.length; ii++) {
+            dBuff = cNod[ii].getDoub();
+            xx += dBuff;
+            xx2 += Math.pow(dBuff, 2);
+            nn++;
+        }
+
+        if (iFunc == iVAR || iFunc == iVARA) {
+            valRes.setVal((nn * xx2 - Math.pow(xx, 2)) / (nn * (nn - 1)));
+        } else if (iFunc == iVARP || iFunc == iVARPA) {
+            valRes.setVal((nn * xx2 - Math.pow(xx, 2)) / Math.pow(nn, 2));
+        } else if (iFunc == iSTDEV || iFunc == iSTDEVA) {
+            valRes.setVal(Math.pow((nn * xx2 - Math.pow(xx, 2)) / (nn * (nn - 1)), 0.5));
+        } else if (iFunc == iSTDEVP || iFunc == iSTDEVPA) {
+            valRes.setVal(Math.pow((nn * xx2 - Math.pow(xx, 2)) / Math.pow(nn, 2), 0.5));
+        }
+
+        return valRes;
+    }
+}
+

+ 20 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xLog10.java

@@ -0,0 +1,20 @@
+package com.lc.ibps.components.verification.funcs;
+
+public class xLog10 {
+    /** Does the actual operation. */
+    public static xValue[] eval(xValue[] data) {
+        xValue[] convert = new xValue[data.length];
+        for(int i = 0 ; i< data.length; i++) {
+            if(!data[i].isDoub()){
+                convert[i] = new xValue();
+                convert[i].setErrVal();
+            }
+            if (data[i].getDoub() <= 0) {
+                convert[i] = new xValue(0);
+            } else {
+                convert[i] = new xValue(Math.log(data[i].getDoub()) / Math.log(10));
+            }
+        }
+        return convert;
+    }
+}

+ 613 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/xValue.java

@@ -0,0 +1,613 @@
+package com.lc.ibps.components.verification.funcs;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.text.DecimalFormat;
+
+public class xValue implements Serializable {
+    private static final byte iNULL = 0;
+    private static final byte iDOUBLE = 1;
+    private static final byte iSTRING = 2;
+    private static final byte iBOOLEAN = 3;
+    private static final byte iREF = 4;
+    private static final byte iOBJECT = 5;
+    private static final byte iNOERR = 6;  //From this point up are Errors
+    private static final byte iERRDIV = 7;
+    private static final byte iERRNA = 8;
+    private static final byte iERRNAME = 9;
+    private static final byte iERRNULL = 10;
+    private static final byte iERRNUM = 11;
+    private static final byte iERRREF = 12;
+    private static final byte iERRVALUE = 13;
+    private static final byte iERRGEN = 14;
+
+    private static final String sERRDIV = "#DIV/0!";
+    private static final String sERRNA = "#N/A";
+    private static final String sERRNAME = "#NAME?";
+    private static final String sERRNULL = "#NULL!";
+    private static final String sERRNUM = "#NUM!";
+    private static final String sERRREF = "#REF!";
+    private static final String sERRVALUE = "#VALUE!";
+
+    /** @deprecated - this attribute is OBFUSCATED for clients. Replace the start of this line for developer javadocs. */
+    public static final String sERRGEN = "#ERROR!";
+
+    //Attributes
+    private byte iType = iNULL;
+    private double valDoub;
+    private Object valObj = null;  //Originally this was a String declaration
+
+    //============SET METHOD SECTION============
+    public xValue(){}
+    public xValue(Object valObj) {
+        if(valObj != null) {
+            if (valObj instanceof Number) {
+                this.iType = iDOUBLE;
+                this.valDoub = ((Number) valObj).doubleValue();
+            }
+            setValFormat(valObj.toString(),true);
+        }
+    }
+    public xValue(double valDoub) {
+        setVal(valDoub);
+    }
+
+    /**
+     * Stores the attributes of valX
+     * @param valX  the value to store
+     */
+    public void setVal(xValue valX) {
+        iType = valX.iType;
+        if (!isErr()) {
+            if ((iType == iDOUBLE) || (iType == iBOOLEAN)) {
+                valDoub = valX.valDoub;
+            } else {
+                valObj = valX.valObj;
+            }
+        }
+    }
+
+    /**
+     * Stores the double, valD
+     * @param valD  the double to store
+     */
+    public void setVal(double valD) {
+        if (Double.isNaN(valD)) {
+            iType = iERRNUM;
+        } else {
+            iType = iDOUBLE;
+            valDoub = valD;
+        }
+    }
+
+    /**
+     * Stores the boolean, valB
+     * @param valB  the boolean to store
+     */
+    public void setVal(boolean valB) {
+        iType = iBOOLEAN;
+        valDoub = (valB ? 1 : 0);
+    }
+
+    /**
+     * Stores the String, valS
+     * @param valS  the String to store
+     */
+    public void setVal(String valS) {
+        iType = iSTRING;
+        valObj = valS;
+    }
+
+
+
+    /**
+     * Stores the Object, valO
+     * @param valO  the Object to store
+     */
+    public void setVal(Object valO) {
+        iType = iOBJECT;
+        valObj = valO;
+    }
+
+    /**
+     * Formats and stores a String in the xValue.
+     * If valS can be converted into a double, date or boolean,
+     * it is stored as such, with all non-numeric symbols removed.
+     * @param valS  the String to format and store
+     */
+    public void setValFormat(String valS) {
+        setValFormat(valS, false);
+    }
+
+    /**
+     * Formats and stores a String in the xValue.
+     * If valS can be converted into a double, date or boolean,
+     * it is stored as such, with all non-numeric symbols removed.
+     * @param valS    the String to format and store
+     * @param bNull   if TRUE, empty strings are set to null
+     */
+    public void setValFormat(String valS, boolean bNull) {
+        //****Needs Work****
+        try {
+            if (valS.lastIndexOf("'") >= 0) {
+                iType = iSTRING;
+                valObj = valS;
+            } else if (valS.length() == 0) {
+                if (bNull) {
+                    iType = iNULL;
+                    valObj = null;
+                } else {
+                    iType = iSTRING;
+                    valObj = valS;
+                }
+            } else {
+                try {
+                    if (valS.indexOf("/") == -1) {
+                        valDoub = getDoubFromStr(valS);
+                    }
+                    iType = iDOUBLE;
+                } catch (NumberFormatException e) {
+                    if (valS.compareToIgnoreCase("TRUE") == 0) {
+                        iType = iBOOLEAN;
+                        valDoub = 1;
+                    } else if (valS.compareToIgnoreCase("FALSE") == 0) {
+                        iType = iBOOLEAN;
+                        valDoub = 0;
+                    } else if (valS.charAt(0) == '#') {
+                        if (valS.equalsIgnoreCase(sERRNA)) {
+                            iType = iERRNA;
+                        } else if (valS.equalsIgnoreCase(sERRDIV)) {
+                            iType = iERRDIV;
+                        } else if (valS.equalsIgnoreCase(sERRNAME)) {
+                            iType = iERRNAME;
+                        } else if (valS.equalsIgnoreCase(sERRNULL)) {
+                            iType = iERRNULL;
+                        } else if (valS.equalsIgnoreCase(sERRNUM)) {
+                            iType = iERRNUM;
+                        } else if (valS.equalsIgnoreCase(sERRREF)) {
+                            iType = iERRREF;
+                        } else if (valS.equalsIgnoreCase(sERRVALUE)) {
+                            iType = iERRVALUE;
+                        } else {
+                            iType = iSTRING;
+                            valObj = valS;
+                        }
+                    } else {
+                        iType = iSTRING;
+                        valObj = valS;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            iType = iSTRING;
+            valObj = valS;
+        }
+    }
+
+
+    //============GET METHOD SECTION============
+
+    /**
+     * Returns the double equivalent of current object.
+     * If object can be converted into a double, it is returned as such,
+     * with all non-numeric symbols removed.
+     * @return  the double equivalent
+     */
+    public double getDoub() {
+        //****Needs Work****
+        if ((iType == iDOUBLE) || (iType == iBOOLEAN)) {
+            return valDoub;
+        } else if (iType == iSTRING) {
+            String sBuff = (String) valObj;
+            if (sBuff.length() == 0) {
+                return 0;
+            } else {
+                return getDoubFromStr(sBuff);
+            }
+        }  else {
+            return 0;
+        }
+    }
+
+    /**
+     * Returns the boolean equivalent of current object.
+     * If object can be converted into a boolean, it is returned as such.
+     * @return  the boolean equivalent
+     */
+    public boolean getBool() {
+        if ((iType == iDOUBLE) || (iType == iBOOLEAN)) {
+            return (valDoub != 0);
+        } else if (iType == iSTRING) {
+            String sBuff = (String) valObj;
+            if (sBuff.length() == 0) {
+                return false;
+            } else if (sBuff.compareToIgnoreCase("TRUE") == 0 || sBuff.compareToIgnoreCase("'TRUE") == 0) {
+                return true;
+            } else if (sBuff.compareToIgnoreCase("FALSE") == 0 || sBuff.compareToIgnoreCase("'FALSE") == 0) {
+                return false;
+            } else {
+                throw new NumberFormatException();
+            }
+        }  else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the String representation of current object.
+     * @return  the String equivalent
+     */
+    public String getStr() {
+        if (iType == iDOUBLE) {
+            String sTemp;
+            if (Math.round(valDoub) == valDoub) {
+                Double dNum = new Double(valDoub);
+                sTemp = Long.toString(dNum.longValue());
+                dNum = null;
+            } else {
+                DecimalFormat df = new DecimalFormat("#.###############");
+                sTemp = df.format(valDoub);
+            }
+            return sTemp;
+        } else if (iType == iBOOLEAN) {
+            if (valDoub != 0) {
+                return "TRUE";
+            } else {
+                return "FALSE";
+            }
+        } else if (iType == iSTRING) {
+            if (valObj == null) {
+                return "";
+            } else {
+                return (String) valObj;
+            }
+        } else if (iType == iNULL) {
+            return "";
+        }  else if (iType == iOBJECT) {
+            return valObj.toString();
+        } else {
+            return getStrErr();
+        }
+    }
+
+
+    /**
+     * Returns the current object.
+     * @return  the object
+     */
+    public Object getObj() {
+        if (iType == iOBJECT) {
+            return valObj;
+        } else if (iType == iSTRING) {
+            return valObj;
+        } else if (iType == iREF) {  //This technically should never be called - we should use getRng
+            return valObj;
+        } else if (iType == iDOUBLE) {
+            return new Double(valDoub);
+        } else if (iType == iBOOLEAN) {
+            return new Long((long) getDoub());
+        } else {
+            return null;
+        }
+    }
+
+    //============IS METHOD SECTION============
+
+    /**
+     * Returns TRUE if the object is of type double.
+     * @return  TRUE if double
+     */
+    public boolean isDoub() {
+        return iType == iDOUBLE;
+    }
+
+    /**
+     * Returns TRUE if the object is of type String.
+     * @return  TRUE if String
+     */
+    public boolean isStr() {
+        return (iType == iSTRING) || (iType == iNULL);
+    }
+
+    /**
+     * Returns TRUE if the object is of really String (ie not NULL) - used for ISTEXT function.
+     * @return  TRUE if String
+     */
+    public boolean isStrReally() {
+        return (iType == iSTRING);
+    }
+
+    /**
+     * Returns TRUE if the object is of type boolean.
+     * @return  TRUE if boolean
+     */
+    public boolean isBool() {
+        return iType == iBOOLEAN;
+    }
+
+    /**
+     * Returns TRUE if the object is of type reference.
+     * @return  TRUE if reference
+     */
+    public boolean isRef() {
+        return iType == iREF;
+    }
+
+    /**
+     * Returns TRUE if the object is of type Object.
+     * @return  TRUE if Object
+     */
+    public boolean isObj() {
+        return iType == iOBJECT;
+    }
+
+    //============SET ERR METHOD SECTION============
+
+    /**
+     * Stores the Error related attributes of valX in current object.
+     * This is similar to setVal(xValue valX), only valX is known to
+     * contain an error.  It is provided for optimization purposes.
+     * @param valX  the error
+     */
+    public void setValErr(xValue valX) {
+        iType = valX.iType;
+    }
+
+    /**
+     * Store a #DIV/0! error in the object.
+     */
+    public void setErrDiv() {
+        iType = iERRDIV;
+    }
+
+    /**
+     * Store an #N/A error in the object.
+     */
+    public void setErrNa() {
+        iType = iERRNA;
+    }
+
+    /**
+     * Store a #NAME! error in the object.
+     */
+    public void setErrName() {
+        iType = iERRNAME;
+    }
+
+    /**
+     * Store a #NULL! error in the object.
+     */
+    public void setErrNull() {
+        iType = iERRNULL;
+    }
+
+    /**
+     * Store a #NUM! error in the object.
+     */
+    public void setErrNum() {
+        iType = iERRNUM;
+    }
+
+    /**
+     * Store a #REF! error in the object.
+     */
+    public void setErrRef() {
+        iType = iERRREF;
+    }
+
+    /**
+     * Store a #VALUE! error in the object.
+     */
+    public void setErrVal() {
+        iType = iERRVALUE;
+    }
+
+    /**
+     * Store a non-Excel (generic) error in the object.
+     */
+    public void setErrGen() {
+        iType = iERRGEN;
+    }
+
+
+    //============GET ERR METHOD SECTION============
+
+    /**
+     * Returns TRUE if the current value is an error.
+     * @return  TRUE if error
+     */
+    public boolean isErr() {
+        return iType > iNOERR;
+    }
+
+    /**
+     * Returns TRUE if the current value is an error, but not a #N/A error.
+     * @return  TRUE if non-#N/A error
+     */
+    public boolean isErrButNA() {
+        return (iType > iNOERR && iType != iERRNA);
+    }
+
+    /**
+     * Returns the String representation of the Error.
+     * @return  the string error
+     */
+    public String getStrErr() {
+        if (iType == iERRDIV) {
+            return sERRDIV;
+        } else if (iType == iERRNA) {
+            return sERRNA;
+        } else if (iType == iERRNAME) {
+            return sERRNAME;
+        } else if (iType == iERRNULL) {
+            return sERRNULL;
+        } else if (iType == iERRNUM) {
+            return sERRNUM;
+        } else if (iType == iERRREF) {
+            return sERRREF;
+        } else if (iType == iERRVALUE) {
+            return sERRVALUE;
+        } else {
+            return sERRGEN;
+        }
+    }
+
+    /**
+     * Returns TRUE if the current value is a blank or null value.
+     * @return  TRUE if blank
+     */
+    public boolean isBlank() {
+        if ((iType == iNULL) || (iType == iSTRING && (((String) valObj).length() == 0))) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns TRUE if the current value is a null value.
+     * @return  TRUE if null
+     */
+    public boolean isEmptyString() {
+        if ((iType == iSTRING) && (((String) valObj).length() == 0)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    //============GET TYPE METHOD SECTION============
+
+    /**
+     * Returns an int value representing the type of value stored
+     * in the current object.
+     * @return  the type
+     */
+    public byte getTyp() {
+        return iType;
+    }
+
+    //============GET??FROMSTR METHOD SECTION============
+
+    /**
+     * Returns a double from a string - if possible
+     * @param sTemp   the string
+     * @return        the double
+     */
+    private double getDoubFromStr(String sOrig) {
+        sOrig = sOrig.trim();
+        while (sOrig.charAt(0) == '+') {
+            sOrig = sOrig.substring(1);
+        }
+
+        int ii = 0;
+        int iLen = sOrig.length();
+        StringBuffer sb = new StringBuffer();
+        boolean bPer = false;
+
+        //Handle $, % and paren negatives
+        if (iLen > 2) {
+            char chr1 = sOrig.charAt(0);
+            if ((chr1 == '-') && (sOrig.charAt(1) == '$')) {
+                sb.append('-');
+                ii = ii + 2;
+            } else {
+                char chr4 = sOrig.charAt(iLen - 1);
+                boolean bNoDolOrPerFound = true;
+                if (chr1 == '$') {
+                    ii++;
+                    chr1 = sOrig.charAt(1);
+                    bNoDolOrPerFound = false;
+                } else if (chr4 == '%') {
+                    bPer = true;
+                    chr4 = sOrig.charAt(iLen - 2);
+                    iLen--;
+                    bNoDolOrPerFound = false;
+                }
+                if ((chr1 == '(') && (chr4 == ')')) {
+                    sb.append('-');
+                    ii++;
+                    iLen--;
+                    if (bNoDolOrPerFound) {
+                        if (sOrig.charAt(1) == '$') {
+                            ii++;
+                        } else if (sOrig.charAt(iLen - 1) == '%') {  //We already subtracted once, so -1 instead of -2
+                            bPer = true;
+                            iLen--;
+                        }
+                    }
+                }
+            }
+        } else if (iLen == 2) {
+            if (sOrig.charAt(0) == '$') {
+                ii++;
+            } else if (sOrig.charAt(1) == '%') {
+                bPer = true;
+                iLen--;
+            }
+        }
+
+        boolean bNum = true;
+
+        char chr = 0;
+        for (; (ii < iLen) && bNum; ii++) {
+            chr = sOrig.charAt(ii);
+            if (Character.isDigit(chr) || (chr == '-') || (chr == '.') || (chr == 'E')) {
+                sb.append(chr);
+            } else if (chr == ',') {
+                //Look ahead
+                if (!Character.isDigit(sOrig.charAt(ii + 1)) ||!Character.isDigit(sOrig.charAt(ii + 2)) ||!Character.isDigit(sOrig.charAt(ii + 3))) {
+                    bNum = false;
+                }
+            } else {
+                bNum = false;
+            }
+        }
+        if (!bNum) {
+            throw new NumberFormatException();
+        } else {
+            //The code below replaces the commented code below it, so that we don't get more decimals than necessary
+            if (bPer) {  //It will bomb here if not double
+                boolean bNeg = (sb.charAt(0) == '-');
+                if (bNeg) {
+                    sOrig = "000" + sb.toString().substring(1);
+                } else {
+                    sOrig = "000" + sb.toString();
+                }
+
+                int iDec = sOrig.indexOf(".");
+                if (iDec == -1) {
+                    iDec = sOrig.length();
+                } else {
+                    sOrig = sOrig.substring(0, iDec) + sOrig.substring(iDec + 1);
+                }
+                iDec = iDec - 2;
+                if (bNeg) {
+                    return -Double.parseDouble(sOrig.substring(0, iDec) + "." + sOrig.substring(iDec));
+                } else {
+                    return Double.parseDouble(sOrig.substring(0, iDec) + "." + sOrig.substring(iDec));
+                }
+            } else {
+                return Double.parseDouble(sb.toString());
+            }
+
+      /*if (bPer) { //It will bomb here if not double
+        return Double.parseDouble(sTemp) / 100;
+      } else {
+        return Double.parseDouble(sTemp);
+      }*/
+        }
+    }
+
+
+    //============CLEANUP SECTION============
+
+    /**
+     * Cleans up the instance of the class.
+     * Used to set all objects to null so that they can be released.
+     */
+    public void cleanUp() {
+        valObj = null;
+    }
+}

+ 23 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/ExcelParserErrorEnum.java

@@ -0,0 +1,23 @@
+package com.lc.ibps.components.verification.model;
+
+import com.lc.ibps.api.base.constants.ServiceContants;
+
+public enum ExcelParserErrorEnum {
+    IncorrectSheetName("未找到此工作表。"),
+    RowLess("工作表中数据条数不够。"),
+    ValueNotDouble("%s: 第%s次检测数据不是数字类型。"),
+    ValueBlank("%s: 第%s次检测数据为空。");
+    private String text;
+
+    ExcelParserErrorEnum(String text) {
+        this.text = text;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+}

+ 67 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/ExcelSheetRecord.java

@@ -0,0 +1,67 @@
+package com.lc.ibps.components.verification.model;
+
+import com.lc.ibps.components.verification.funcs.xValue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ExcelSheetRecord {
+
+    private String sheetName;
+    private List<Map> data;
+    //标本名称:检测值
+    private Map<String, xValue[]> convertedData;
+
+    private List<String> errors = new ArrayList<>();
+
+    public ExcelSheetRecord(String sheetName, List<Map> data) {
+        this.sheetName = sheetName;
+        this.data = data;
+    }
+
+    public Map<String, xValue[]> getConvertedData() {
+        return convertedData;
+    }
+
+    public void convert(InspectionConfigVO config, String configSheetName) {
+        convertedData = new HashMap<>();
+
+        if(!configSheetName.equals(sheetName)){
+            errors.add(ExcelParserErrorEnum.IncorrectSheetName.getText());
+            return;
+        }
+        if (data.size() < config.getRepeatNum()) {
+            errors.add(ExcelParserErrorEnum.RowLess.getText());
+            return;
+        }
+        for (String sName : config.getSpecimensName()) {
+            convertedData.put(sName, new xValue[config.getRepeatNum()]);
+        }
+        for (int i = 0; i < config.getRepeatNum(); i++) {
+            Map<String, Object> map = data.get(i);
+            for (String sName : config.getSpecimensName()) {
+//                Object val = map.get(sName + "_" + InspectionItemVO.DISPLAY_VALUE);
+                Object val = map.get(sName);
+                xValue value = new xValue(val);
+                if(value.isBlank()){
+                    errors.add(String.format(ExcelParserErrorEnum.ValueBlank.getText(),sName,i+1));
+                }else if(!value.isDoub()){
+                    errors.add(String.format(ExcelParserErrorEnum.ValueNotDouble.getText(),sName,i+1));
+                }else {
+                    convertedData.get(sName)[i] = value;
+                }
+            }
+        }
+    }
+
+    public List<String> getErrors() {
+        return errors;
+    }
+
+    public String getSheetName() {
+        return sheetName;
+    }
+}
+

+ 24 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/FunctionEnum.java

@@ -0,0 +1,24 @@
+package com.lc.ibps.components.verification.model;
+
+public enum FunctionEnum {
+    SD("标准差(SD)"),
+    AVERAGE("均值"),
+    CV("变异系数(CV)"),
+    TARGET("理论值/靶值"),
+    ABSDEV("绝对偏倚"),
+    RELDEV("相对偏倚"),
+    A("截距(a)"),
+    B("斜率(b)"),
+    R("相关系数(r)"),
+    RVALUE("R值"),//检测均值/预期值×100%
+    LRE("线性回归方程");
+    private String text;
+
+    FunctionEnum(String text) {
+        this.text = text;
+    }
+
+    public String getText() {
+        return text;
+    }
+}

+ 123 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/InspectionConfigVO.java

@@ -0,0 +1,123 @@
+package com.lc.ibps.components.verification.model;
+
+import java.time.LocalDate;
+import java.util.Date;
+
+public class InspectionConfigVO {
+
+    //检测指标名称
+    private String name;
+    //检验天数
+    private int days;
+    //标本数
+    private int specimensNum;
+    // 标本名
+    private String[] specimensName;
+    //重复次数
+    private int repeatNum;
+    //是否需要数据转换(对数)
+    private boolean isConvert = false;
+
+    private FunctionEnum[] func;
+
+    private double[] targetValue;
+
+    public InspectionConfigVO(String name, int days, int specimensNum, String[] specimensName,
+                              int repeatNum, LocalDate startDate,boolean isConvert) {
+        this.name = name;
+        this.days = days;
+        this.specimensNum = specimensNum;
+        this.specimensName = specimensName;
+        this.repeatNum = repeatNum;
+        this.startDate = startDate;
+        this.isConvert = isConvert;
+    }
+
+    public InspectionConfigVO(String name, int days, int specimensNum, String[] specimensName, int repeatNum,
+                              boolean convert, FunctionEnum[] func, double[] targetValue, LocalDate startDate) {
+        this.name = name;
+        this.days = days;
+        this.specimensNum = specimensNum;
+        this.specimensName = specimensName;
+        this.repeatNum = repeatNum;
+        this.isConvert = convert;
+        this.func = func;
+        this.targetValue = targetValue;
+        this.startDate = startDate;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    private LocalDate startDate = LocalDate.now();
+
+    public int getDays() {
+
+        return days;
+    }
+
+    public void setDays(int days) {
+        this.days = days;
+    }
+
+    public int getSpecimensNum() {
+        return specimensNum;
+    }
+
+    public void setSpecimensNum(int specimensNum) {
+        this.specimensNum = specimensNum;
+    }
+
+    public String[] getSpecimensName() {
+        return specimensName;
+    }
+
+    public void setSpecimensName(String[] specimensName) {
+        this.specimensName = specimensName;
+    }
+
+    public int getRepeatNum() {
+        return repeatNum;
+    }
+
+    public void setRepeatNum(int repeatNum) {
+        this.repeatNum = repeatNum;
+    }
+
+    public LocalDate getStartDate() {
+        return startDate;
+    }
+
+    public void setStartDate(LocalDate startDate) {
+        this.startDate = startDate;
+    }
+
+    public boolean isConvert() {
+        return isConvert;
+    }
+
+    public void setConvert(boolean convert) {
+        isConvert = convert;
+    }
+
+    public FunctionEnum[] getFunc() {
+        return func;
+    }
+
+    public void setFunc(FunctionEnum[] func) {
+        this.func = func;
+    }
+
+    public double[] getTargetValue() {
+        return targetValue;
+    }
+
+    public void setTargetValue(double[] targetValue) {
+        this.targetValue = targetValue;
+    }
+}

+ 257 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/InspectionItemVO.java

@@ -0,0 +1,257 @@
+package com.lc.ibps.components.verification.model;
+
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.lc.ibps.components.poi.excel.entity.ExportParams;
+import com.lc.ibps.components.poi.excel.entity.ImportParams;
+import com.lc.ibps.components.poi.excel.entity.enmus.ExcelType;
+import com.lc.ibps.components.poi.excel.entity.params.ExcelExportEntity;
+import com.lc.ibps.components.poi.excel.entity.vo.BaseEntityTypeConstants;
+import com.lc.ibps.components.verification.excel.PVExcelExportStyler;
+import com.lc.ibps.components.verification.excel.PVExcelUtil;
+import com.lc.ibps.components.verification.funcs.xValue;
+import org.apache.poi.ss.usermodel.Workbook;
+
+import java.io.InputStream;
+import java.time.LocalDate;
+import java.util.*;
+
+/**
+ * 每个检测指标对应的数据
+ */
+public class InspectionItemVO {
+
+    public static String DISPLAY_NUMBER = "次数";
+    public static String DISPLAY_VALUE = "检测值";
+
+    public static String DISPLAY_LOG = "对数值";
+
+    public static String DISPLAY_DATE = "实验日期";
+
+    private InspectionConfigVO config;
+
+    //样本名 : 检查数据
+    @JSONField(serialize = false)
+    private Map<String, SpecimensCalcVO> record = new HashMap<>();;
+    @JSONField(serialize = false)
+    private ItemCalcVO itemCalcVO;
+    @JSONField(serialize = false)
+    private boolean dataPass = false;
+    @JSONField(serialize = false)
+    private Map<String, List<String>> errorMessage = new HashMap<>();
+    public InspectionItemVO(InspectionConfigVO config,Map<String, double[]> data){
+        this.config = config;
+        this.dataPass = true;
+        setData(data);
+        buildItemCalcVO();
+    }
+    public InspectionItemVO(InspectionConfigVO config) {
+        this.config = config;
+    }
+
+    public Workbook exportExcelTemplate() {
+        List<ExcelExportEntity> entity = new ArrayList<ExcelExportEntity>();
+
+        List<ExcelExportEntity> temp = new ArrayList<ExcelExportEntity>();
+        ExcelExportEntity e1 = new ExcelExportEntity(DISPLAY_NUMBER, "number");
+//        e1.setMergeVertical(true);
+        e1.setType(BaseEntityTypeConstants.DoubleType);
+        entity.add(e1);
+
+
+        for (int i = 0; i < config.getSpecimensNum(); i++) {
+            ExcelExportEntity e2 = new ExcelExportEntity(config.getSpecimensName()[i], "input");
+            entity.add(e2);
+        }
+//        ExcelExportEntity excelEntity = new ExcelExportEntity("", "inspection");
+//        excelEntity.setList(temp);
+//        entity.add(excelEntity);
+        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+        Map<String, Object> map;
+        for (int i = 1; i <= config.getRepeatNum(); i++) {
+            map = new HashMap<String, Object>();
+            map.put("number", i);
+//            map.put("value", "");
+
+//            List<Map<String, Object>> tempList = new ArrayList<Map<String, Object>>();
+//            tempList.add(map);
+//            map.put("inspection", tempList);
+
+            list.add(map);
+        }
+        List<ExportParams> exportParamsList = new ArrayList<ExportParams>();
+        LocalDate startDate = config.getStartDate();
+        for (int i = 0; i < config.getDays(); i++) {
+            ExportParams exportParams = new ExportParams(config.getName() + " 数据导入模板", startDate.toString());
+            exportParams.setStyle(PVExcelExportStyler.class);
+            exportParamsList.add(exportParams);
+            startDate = startDate.plusDays(1);
+            exportParams.setType(ExcelType.XSSF);
+        }
+        Workbook workbook = PVExcelUtil.exportExcelTemplateWithMultiSheet(exportParamsList, entity, list);
+
+        return workbook;
+    }
+
+    public Map<String, Object> buildExportReportParams() {
+        Map<String, Object> map = new HashMap<>();
+        //        server.createSheet(workbook, (ExportParams) map.get("params"),
+//                (List<ExcelExportEntity>) map.get("entity"), (Collection<?>) map.get("data"));
+//        List<ExcelExportEntity>
+        ExportParams exportParams = new ExportParams(config.getName() + " 性能验证报告", config.getName());
+        exportParams.setStyle(PVExcelExportStyler.class);
+        exportParams.setType(ExcelType.XSSF);
+        map.put("params", exportParams);
+
+        List<ExcelExportEntity> entity = new ArrayList<>();
+        ExcelExportEntity e1 = new ExcelExportEntity(DISPLAY_DATE, "date");
+        e1.setMergeVertical(true);
+        entity.add(e1);
+        ExcelExportEntity e2 = new ExcelExportEntity(DISPLAY_NUMBER, "number");
+        e2.setType(BaseEntityTypeConstants.DoubleType);
+        entity.add(e2);
+
+
+        for (int i = 0; i < config.getSpecimensNum(); i++) {
+            List<ExcelExportEntity> temp = new ArrayList<ExcelExportEntity>();
+
+
+            ExcelExportEntity e3 = new ExcelExportEntity(config.getSpecimensName()[i], "value");
+            temp.add(e3);
+            ExcelExportEntity excelEntity = new ExcelExportEntity("", "inspection" + i);
+            excelEntity.setList(temp);
+            entity.add(excelEntity);
+            if (config.isConvert()) {
+                excelEntity.setName(config.getSpecimensName()[i]);
+                e3.setName(DISPLAY_VALUE);
+                ExcelExportEntity e4 = new ExcelExportEntity(DISPLAY_LOG, "log");
+                temp.add(e4);
+            }
+
+        }
+        map.put("entity", entity);
+
+        List<Map<String, Object>> data = new ArrayList<>();
+        LocalDate date = config.getStartDate();
+        for (int i = 0; i < config.getDays(); i++) {
+            for (int j = 0; j < config.getRepeatNum(); j++) {
+                Map<String, Object> item = new HashMap<>();
+                item.put("date", date.toString());
+                item.put("number", j + 1);
+                for (int k = 0; k < config.getSpecimensNum(); k++) {
+                    List<Map<String, Object>> sItem = new ArrayList<>();
+                    final SpecimensCalcVO specimensCalcVO = record.get(config.getSpecimensName()[k]);
+                    Map<String, Object> sValue = new HashMap<>();
+                    double d = specimensCalcVO.getData()[i * config.getRepeatNum() + j].getDoub();
+//                    DecimalFormat decimalFormat=new DecimalFormat("0.##E0");//格式化设置
+//                    String s = decimalFormat.format(d);
+                    sValue.put("value", d);
+                    if (config.isConvert()) {
+                        sValue.put("log", specimensCalcVO.getConvertedData()[i * config.getRepeatNum() + j].getDoub());
+                    }
+                    sItem.add(sValue);
+                    item.put("inspection" + k, sItem);
+                }
+                data.add(item);
+            }
+            date = date.plusDays(1);
+        }
+        map.put("data", data);
+        map.put("item", this);
+
+        return map;
+    }
+
+    public void importExcelRecord(InputStream inputstream) {
+        ImportParams params = new ImportParams();
+        params.setTitleRows(2);
+        params.setHeadRows(1);
+        params.setSheetNum(config.getDays());
+        List<ExcelSheetRecord> list = PVExcelUtil.importExcel(inputstream, Map.class, params);
+        LocalDate startDate = config.getStartDate();
+        for (ExcelSheetRecord record : list) {
+            record.convert(config, startDate.toString());
+            if (record.getErrors().size() > 0) {
+                errorMessage.put(startDate.toString(), record.getErrors());
+            }
+            startDate = startDate.plusDays(1);
+        }
+        if (errorMessage.size() > 0) {
+            return;
+        } else {
+            dataPass = true;
+        }
+        for (String sName : config.getSpecimensName()) {
+            final xValue[] total = new xValue[config.getRepeatNum() * config.getDays()];
+            for (int j = 0; j < list.size(); j++) {
+                final xValue[] xValues = list.get(j).getConvertedData().get(sName);
+                for (int k = 0; k < xValues.length; k++) {
+                    total[j * xValues.length + k] = xValues[k];
+                }
+            }
+            record.put(sName, new SpecimensCalcVO(total, config.isConvert()));
+        }
+        buildItemCalcVO();
+    }
+
+    private void buildItemCalcVO() {
+        if (config.getTargetValue() == null) return;
+
+        xValue[] specimens = new xValue[config.getSpecimensNum()];
+        xValue[] target = new xValue[config.getSpecimensNum()];
+        for (int i = 0; i < config.getSpecimensNum(); i++) {
+            String sName = config.getSpecimensName()[i];
+            record.get(sName).setTargetValue(config.getTargetValue()[i]);
+            specimens[i] = record.get(sName).getAverage();
+            target[i] = new xValue(config.getTargetValue()[i]);
+        }
+        itemCalcVO = new ItemCalcVO(specimens, target);
+    }
+
+    public Map<String, SpecimensCalcVO> getRecord() {
+        return record;
+    }
+
+    public void setRecord(Map<String, SpecimensCalcVO> record) {
+        this.record = record;
+    }
+
+    public InspectionConfigVO getConfig() {
+        return config;
+    }
+
+    public void setConfig(InspectionConfigVO config) {
+        this.config = config;
+    }
+
+    public boolean isDataPass() {
+        return dataPass;
+    }
+
+    public Map<String, List<String>> getErrorMessage() {
+        return errorMessage;
+    }
+
+    public ItemCalcVO getItemCalcVO() {
+        return itemCalcVO;
+    }
+    public Map<String, double[]> getData(){
+        Map<String, double[]> data = new HashMap<>();
+        for (String name : record.keySet()) {
+            data.put(name,record.get(name).getStoreData());
+        }
+        return data;
+    }
+
+    private void setData(Map<String, double[]> map){
+            for (String name : map.keySet()){
+                final double[] data = map.get(name);
+                xValue[] d = new xValue[data.length];
+                for (int i = 0; i<data.length;i++){
+                    d[i] = new xValue(data[i]);
+                }
+                record.put(name,new SpecimensCalcVO(d,config.isConvert()));
+            }
+    }
+
+}

+ 42 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/InspectionVO.java

@@ -0,0 +1,42 @@
+package com.lc.ibps.components.verification.model;
+
+import com.lc.ibps.components.poi.excel.entity.enmus.ExcelType;
+import com.lc.ibps.components.verification.excel.PVExcelUtil;
+import org.apache.poi.ss.usermodel.Workbook;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class InspectionVO {
+
+    private String name;
+    private List<InspectionItemVO> item = new ArrayList<>();
+
+    public Workbook exportExcelReport(boolean isSummary) {
+        List<Map<String, Object>> list = new ArrayList<>();
+        for (InspectionItemVO item : item) {
+            list.add(item.buildExportReportParams());
+        }
+
+        Workbook workbook = PVExcelUtil.exportExcelReport(list, ExcelType.XSSF);
+
+        return workbook;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<InspectionItemVO> getItem() {
+        return item;
+    }
+
+    public void setItem(List<InspectionItemVO> item) {
+        this.item = item;
+    }
+}

+ 61 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/ItemCalcVO.java

@@ -0,0 +1,61 @@
+package com.lc.ibps.components.verification.model;
+
+import com.lc.ibps.components.verification.funcs.xFuncArray2Args;
+import com.lc.ibps.components.verification.funcs.xValue;
+
+//多个标本之间的对比计算
+public class ItemCalcVO {
+    //多个样本均值 y
+    private xValue[] specimensValue;
+    //样本的标示值/理论值 x
+    private xValue[] targetValue;
+    //截距(a)
+    private xValue a;
+    //斜率(b)
+    private xValue b;
+    //相关系数r
+    private xValue r;
+
+    public ItemCalcVO(xValue[] specimensValue, xValue[] targetValue) {
+        this.specimensValue = specimensValue;
+        this.targetValue = targetValue;
+        b = xFuncArray2Args.evalArgs(specimensValue, targetValue, xFuncArray2Args.iSLOPE);
+        a = xFuncArray2Args.evalArgs(specimensValue, targetValue, xFuncArray2Args.iINTERCEPT);
+        r = xFuncArray2Args.evalArgs(specimensValue, targetValue, xFuncArray2Args.iCORREL);
+    }
+
+    public xValue[] getSpecimensValue() {
+        return specimensValue;
+    }
+
+    public xValue[] getTargetValue() {
+        return targetValue;
+    }
+
+    public xValue getA() {
+        return a;
+    }
+
+    public xValue getB() {
+        return b;
+    }
+
+    public xValue getR() {
+        return r;
+    }
+
+    public String getLRE() {
+        //y = bx + a
+        if(a.getDoub() > 0){
+            return String.format("y = %.4fx + %.4f", b.getDoub(), a.getDoub());
+        }else if(a.getDoub() <0){
+            return String.format("y = %.4fx - %.4f", b.getDoub(), -a.getDoub());
+        }else {
+            return String.format("y = %.4fx", b.getDoub());
+        }
+    }
+
+    public static void main(String[] args) {
+        System.out.println(String.format("y = %.4fx + %.4f", 1.3454523, 0.234556));
+    }
+}

+ 116 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/SpecimensCalcVO.java

@@ -0,0 +1,116 @@
+package com.lc.ibps.components.verification.model;
+
+import com.lc.ibps.components.verification.funcs.xAverage;
+import com.lc.ibps.components.verification.funcs.xFuncStdevVar;
+import com.lc.ibps.components.verification.funcs.xLog10;
+import com.lc.ibps.components.verification.funcs.xValue;
+
+/**
+ * 单列数据计算
+ */
+public class SpecimensCalcVO {
+
+    private xValue[] data;
+
+
+
+    private xValue[] convertedData;
+
+
+    ////////////////////
+    //均值
+    private xValue average;
+    //标准差
+    private xValue sd;
+    //变异系数百分比 = sd/average
+    private xValue cv;
+    //绝对偏倚  average - targetValue;
+    private xValue absDev;
+    //相对偏倚 = 绝对偏倚 / targetValue
+    private xValue relDev;
+    //检测均值对数/预期值对数×100%
+    private xValue rvalue;
+    //靶值
+    private Double targetValue;
+
+    public SpecimensCalcVO(xValue[] data, boolean isConvert) {
+        this.data = data;
+        if (!isConvert) convertedData = data;
+        else convert();
+    }
+
+    public xValue getAverage() {
+        if (average == null) average = xAverage.eval(convertedData);
+        return average;
+    }
+
+    public xValue getSd() {
+        if (sd == null) sd = xFuncStdevVar.evalArgs(convertedData, xFuncStdevVar.iSTDEV);
+        return sd;
+    }
+
+    public xValue getCv() {
+        if (cv != null) return cv;
+        cv = new xValue();
+        if (getSd().isErr() || getAverage().isErr()) cv.setErrNa();
+        else cv.setVal(sd.getDoub() / average.getDoub());
+        return cv;
+    }
+
+    private void convert() {
+            convertedData = xLog10.eval(data);
+    }
+
+    public xValue getAbsDev() {
+        if(absDev != null) return absDev;
+        if (targetValue == null) {
+            return new xValue();
+        }
+        absDev = new xValue( getAverage().getDoub() - targetValue );
+        return absDev;
+    }
+
+    public xValue getRelDev() {
+        if(relDev != null) return relDev;
+        if (targetValue == null) {
+            return new xValue();
+        }
+        relDev = new xValue( getAbsDev().getDoub()/targetValue );
+        return relDev;
+    }
+    //检测均值/预期值×100%
+    public xValue getRvalue() {
+        if(rvalue != null) return rvalue;
+        if (targetValue == null) {
+            return new xValue();
+        }
+        rvalue = new xValue( getAverage().getDoub()/targetValue );
+        return rvalue;
+    }
+
+
+    public xValue[] getData() {
+        return data;
+    }
+
+    public xValue[] getConvertedData() {
+        return convertedData;
+    }
+
+    public Double getTargetValue() {
+        return targetValue;
+    }
+
+    public void setTargetValue(Double targetValue) {
+        this.targetValue = targetValue;
+    }
+
+    public double[] getStoreData(){
+        double[] d = new double[data.length];
+        for (int i = 0; i<data.length;i++){
+            d[i] = data[i].getDoub();
+        }
+        return d;
+    }
+
+}

+ 18 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/service/PerformanceVerificationService.java

@@ -0,0 +1,18 @@
+package com.lc.ibps.components.verification.service;
+
+import com.lc.ibps.components.verification.model.InspectionItemVO;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+public interface PerformanceVerificationService {
+
+    InspectionItemVO importExcelRecord(String name,
+                                       String id,
+                                       MultipartFile applyFiles) throws IOException;
+
+    Workbook exportExcelTemplateExport(String name, String id);
+
+    Workbook exportExcelReport(String name, String id);
+}

+ 56 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/service/impl/PerformanceVerificationServiceImpl.java

@@ -0,0 +1,56 @@
+package com.lc.ibps.components.verification.service.impl;
+
+import com.lc.ibps.components.verification.model.InspectionConfigVO;
+import com.lc.ibps.components.verification.model.InspectionItemVO;
+import com.lc.ibps.components.verification.model.InspectionVO;
+import com.lc.ibps.components.verification.service.PerformanceVerificationService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.time.LocalDate;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class PerformanceVerificationServiceImpl implements PerformanceVerificationService {
+
+    //todo:
+    private Map<String,InspectionItemVO> data = new HashMap<>();
+    @Override
+    public InspectionItemVO importExcelRecord(String name, String id, MultipartFile applyFiles) throws IOException {
+
+        InspectionConfigVO config = getInspectionConfig(name, id);
+        InspectionItemVO item = new InspectionItemVO(config);
+        item.importExcelRecord(applyFiles.getInputStream());
+        data.put(id+name,item);
+        return item;
+    }
+
+    @Override
+    public Workbook exportExcelTemplateExport(String name, String id) {
+        InspectionConfigVO config = getInspectionConfig(name, id);
+        InspectionItemVO item = new InspectionItemVO(config);
+        Workbook workbook = item.exportExcelTemplate();
+        return workbook;
+    }
+
+    @Override
+    public Workbook exportExcelReport(String name, String id) {
+        InspectionVO inspectionVO = new InspectionVO();
+        InspectionItemVO item = data.get(id+name);
+        if(item == null) throw new RuntimeException("can't find this config");
+        inspectionVO.getItem().add(item);
+        Workbook workbook = inspectionVO.exportExcelReport(StringUtils.isNotBlank(name));
+        return workbook;
+    }
+
+    private InspectionConfigVO getInspectionConfig(String name, String id) {
+
+        InspectionConfigVO config = new InspectionConfigVO("线性范围", 1, 7,
+                new String[]{"E8", "E7", "E6", "E5", "E4", "E3", "E2"}, 3, LocalDate.now(), true);
+        return config;
+    }
+}