java导入excel更新设备经纬度度数或者度分秒

news2025/4/13 3:25:26

在这里插入图片描述

文章目录

  • 一、背景介绍
  • 二、页面效果
  • 三、代码
    • 0.pom.xml
    • 1.ImportDevice.vue
    • 2.ImportDeviceError.vue
    • 3.system.js
    • 4.DeviceManageControl
    • 5.DeviceManageUserControl
    • 6.Repeater
    • 7.FileUtils
    • 8.ResponseModel
    • 9.EnumLongitudeLatitude
    • 10.词条
  • 四、注意点
  • 本人其他相关文章链接

一、背景介绍

项目采用:Arco Design+java+mysql+springboot+vue3

项目中转台存入有2种:

  • 第一种南向上报入库;
  • 第二种手动添加入库;

但是这两种方式中转台都没有经纬度和海拔值,所以需要导入excel去批量更新经纬度和海拔。

同时参数配置中展示效果有2种:

  • 度数显示
  • 度分秒显示

因为展示效果有2种,所以excel导入模版也有2种不同的模版,本篇文章就是记录excel导入更新入库,同时记录“度数”和“度分秒”之间的转换方式。

二、页面效果

度数显示

在这里插入图片描述
在这里插入图片描述

度分秒显示

在这里插入图片描述
在这里插入图片描述

下载excel模版和导入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据库表字段设计

在这里插入图片描述

导入失败错误提示,展示所有错误的信息

在这里插入图片描述

导入接口会返回详细错误提示

在这里插入图片描述

三、代码

0.pom.xml

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

1.ImportDevice.vue

<template>
  <a-modal :width="570" :align-center="true">
    <template #title>
      <div class="title">{{ openTitle }}</div>
    </template>
    <div class="frameParent">
      <div class="frameWrapper">
        <div class="frameGroup">
          <div class="textWrapper">
            <div class="text">{{$t('ImportTempletDownLoad')}}</div>
          </div>
          <div class="frameContainer">
            <div class="iconBaseParent">
              <div class="iconBase"> <icon-download />
              </div>
              <div class="text1" @click="templateOne">{{$t('LngLatDegree')}}</div>
            </div>
            <div class="iconBaseParent">
              <div class="iconBase"> <icon-download />
              </div>
              <div class="text1" @click="templateTwo">{{$t('LngLatDegreeMinuteSecond')}}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="frameDiv">
        <div class="groupWrapper">
          <div class="groupDiv">
            <div class="textParent">
              <div class="text3">{{$t('BrowseImport')}}</div>
              <div class="parent">
                <a-input class="div" v-model="fileName" disabled />
                <a-upload  accept=".xlsx, .xls"  @change="onChange" :auto-upload="false" :show-file-list="false">
                  <template #upload-button>
                    <svg-loader class="frameIcon" name="import-file"></svg-loader>
                  </template>
                </a-upload>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <template #footer>
      <a-button @click="closeDevice()">{{$t('cancelLabel')}}</a-button>
      <a-button type="primary" @click="saveDevice()">{{$t('ExportTaskEnter')}}</a-button>
    </template>
  </a-modal>
</template>

<script setup>
import {defineEmits, inject, ref} from "vue";
import { Message } from "@arco-design/web-vue";
import {importDevive} from "@/views/pages/system/system.js";
const t = inject('t')
const openTitle = ref('')
const emits = defineEmits(['receiveImportError','refresh-flag'])

const templateOne = () => {
  window.open(`${location.origin}/api/deviceManage/downloadImportTemplateAboutDegrees`)
}
const templateTwo = () => {
  window.open(`${location.origin}/api/deviceManage/downloadImportTemplateAboutDMS`)
}
const files = ref([]);
const fileName = ref('');

const onChange = (fileList) => {
  files.value = [];
  if (fileList.length > 0) {
    const lastUploadedFile = fileList[fileList.length - 1];
    const lastFileName = lastUploadedFile.name;
    fileName.value = lastFileName;
    files.value.push(lastUploadedFile)
  }
};

const closeDevice =() => {
  emits('refresh-flag', 1)
}

const saveDevice = () => {
  const uploadedFile = files.value;
  const formData = new FormData();
  formData.append("file", uploadedFile[0].file);

  importDevive(formData).then(response =>{
    if (response.code === 200) {
      Message.success(t('HeaderSuccessfulResult'))
      emits('refresh-flag', 1)
    } else {
      emits('receiveImportError', response.data);
    }
  })
};

</script>

<style scoped lang="less">
.text {
  position: relative;
  line-height: 22px;
}

.textWrapper {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
}

.iconBase {
  width: 20px;
  position: relative;
  height: 20px;
  overflow: hidden;
  flex-shrink: 0;
}

.text1 {
  position: relative;
  text-decoration: underline;
  line-height: 22px;
  cursor: pointer;
}

.iconBaseParent {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
}

.frameContainer {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 32px;
  text-align: center;
  color: #3348ff;
}

.frameGroup {
  width: 400px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 16px;
}

.frameWrapper {
  align-self: stretch;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  align-content: center;
  padding: 0px 20px 20px;
}

.text3 {
  align-self: stretch;
  position: relative;
  line-height: 22px;
}

.div1 {
  position: relative;
}

.div {
  position: absolute;
  top: 0px;
  left: 0px;
  border-radius: 8px;
  background-color: #fbfcfd;
  border: 1px solid #dde4ed;
  box-sizing: border-box;
  width: 400px;
  height: 40px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  padding: 8px 10px;
}

.frameIcon {
  position: absolute;
  top: 6px;
  left: 364px;
  width: 28px;
  height: 28px;
}

.parent {
  width: 400px;
  position: relative;
  height: 40px;
  color: #202b40;
  font-family: 'PingFang TC';
}

.textParent {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 400px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 4px;
}

.groupDiv {
  width: 400px;
  position: relative;
  height: 66px;
}

.groupWrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.frameDiv {
  align-self: stretch;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  align-content: center;
  padding: 20px;
}

.frameParent {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  color: #778091;
}

.secondaryButton1text {
  box-shadow: 0px -2px 2px rgba(48, 48, 48, 0.1) inset, 0px 12px 12px rgba(255, 255, 255, 0.12) inset;
  border-radius: 8px;
  background-color: #fff;
  border: 1px solid #dde4ed;
  box-sizing: border-box;
  height: 36px;
  overflow: hidden;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  padding: 5px 16px;
}

.buttontertiaryButtonnormal {
  height: 36px;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  justify-content: flex-start;
}

.primaryButton {
  box-shadow: 0px -2px 2px rgba(48, 48, 48, 0.1) inset, 0px 12px 12px rgba(255, 255, 255, 0.12) inset;
  border-radius: 8px;
  background-color: #004ce5;
  height: 36px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  padding: 5px 16px;
  box-sizing: border-box;
}

.buttonprimaryButtonnormal {
  border-radius: 8px;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  justify-content: flex-start;
  text-align: left;
  color: #fff;
}

.button {
  align-self: stretch;
  border-radius: 0px 0px 12px 12px;
  background-color: #f6f7f9;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  padding: 16px 20px;
  gap: 12px;
  text-align: center;
  color: #455471;
}

.headerParent {
  width: 100%;
  position: relative;
  border-radius: 12px;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 20px;
  text-align: left;
  font-size: 14px;
  color: #202b40;
  font-family: 'PingFang SC';
}
</style>

2.ImportDeviceError.vue

<template>
  <a-modal :width="1200" :align-center="true" :hide-cancel="true">
    <template #title>
      <div class="title">{{ openTitle }}</div>
    </template>

    <div class="table-line">
      <a-table :data="errorTableData" :bordered="false" :pagination="false" :loading="errorTableLoading" v-model:selected-keys="errorSelectedKeys" row-key="serialNo">
        <template #columns>
          <a-table-column dataIndex="alias" :title="$t('RepeaterAlias')" :tooltip="true"></a-table-column>
          <a-table-column dataIndex="serialNo" :title="$t('SerialNo')" :tooltip="true"></a-table-column>
          <a-table-column dataIndex="lng" :title="$t('Longitude_Degree')" :tooltip="true">
            <template #cell="{ record }">
              <div style="display: flex; align-items: center;">
                <a-select v-model="record.lngOr" style="margin-right: 8px;width: 100px" disabled>
                  <a-option :value=0 :label="$t('EastLongitude')"></a-option>
                  <a-option :value=1 :label="$t('WestLongitude')"></a-option>
                </a-select>
                {{record.lng}}
              </div>
            </template>
          </a-table-column>
          <a-table-column dataIndex="lat" :title="$t('Latitude_Degree')" :tooltip="true">
            <template #cell="{ record }">
              <div style="display: flex; align-items: center;">
                <a-select v-model="record.latOr" style="margin-right: 8px;width: 100px" disabled>
                  <a-option :value=0 :label="$t('NorthLatitude')"></a-option>
                  <a-option :value=1 :label="$t('SouthLatitude')"></a-option>
                </a-select>
                {{record.lat}}
              </div>
            </template>
          </a-table-column>
          <a-table-column dataIndex="elevation" :title="$t('Elevation')" :tooltip="true">
            <template #cell="{ record }">
              {{record.elevation}}
            </template>
          </a-table-column>
          <a-table-column dataIndex="importErrorMessage" :title="$t('CauseOfImportFailure')" :tooltip="true"></a-table-column>
        </template>
      </a-table>
    </div>
  </a-modal>
</template>

<script setup>
import {ref, defineExpose} from "vue";
const errorTableData = ref([])
const errorSelectedKeys = ref([])
const errorTableLoading = ref(false)
const openTitle = ref('')

const setData = (record, title) => {
  openTitle.value = title
  if (null != record) {
    errorTableData.value = record;
  }
}

defineExpose({
  setData
})
</script>

<style scoped lang="less">
.table-line {
  box-sizing: border-box;
  width: 1200px;
  height: 500px;
}
</style>

3.system.js

import { $http, Method } from "@/http";

export const importDevive = (data) => {
  return $http({
    url: `/api/deviceManage/importData`,
    method: Method.POST,
    headers: {
      'Content-Type': 'multipart/form-data',
      'X-Requested-With': 'XMLHttpRequest'
    },
    data
  })
}

4.DeviceManageControl

@Operation(summary = "导入数据")
@PostMapping(value = "/importData")
public ResponseModel importData(@RequestParam MultipartFile file) {
    return deviceManageUserControl.importData(file);
}

5.DeviceManageUserControl

public ResponseModel importData(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        String extension = FileUtils.getFileExtension(fileName);
        if (!extension.equals(".xls") && !extension.equals(".xlsx")) {
            return ResponseModel.ofError(languageFind.findKey("Device_Excel_ColumnIsNotExits"));
        }
        int excelColumnCount = FileUtils.getExcelColumnCount(file);
        if (excelColumnCount != 8 && excelColumnCount != 12) {
            return ResponseModel.ofError(languageFind.findKey("Device_Excel_ColumnIsNotExits"));
        }
        if (excelColumnCount > 1000) {
            return ResponseModel.ofError(languageFind.findKey("Device_Excel_RepeatData_1000MaximumData"));
        }
        if (excelColumnCount == 8) {
            return writeDegree(file);
        } else if (excelColumnCount == 12) {
            return writeDegreeMiuSec(file);
        }
        return ResponseModel.ofSuccess();
    }

    /**
     * 写入度的形式
     * @param file 文件
     * @return 结果
     */
    public ResponseModel writeDegree(MultipartFile file) {
        List<Repeater> repeaterList = new ArrayList<>();
        List<Repeater> listError = new ArrayList<>();
        Repeater repeater = null;
        List<String> excelValuesList = new ArrayList<>();
        List<String> serialNoList = new ArrayList<>();

        try {
            Account account = (Account) SecurityUtils.getSubject().getPrincipal();
            List<Repeater> authorityRepeaters = commonIClient.getAuthorityRepeaters(account.getUserName());
            String fileName = file.getOriginalFilename();
            InputStream inputStream = file.getInputStream();
            Workbook workbook = null;
            if (fileName.indexOf(".xlsx") > 0) {
                workbook = new XSSFWorkbook(inputStream);
            } else if (fileName.indexOf(".xls") > 0) {
                workbook = new HSSFWorkbook(inputStream);
            }
            Sheet sheet = workbook.getSheetAt(0);
            int lastNum = sheet.getLastRowNum();
            Row row = sheet.getRow(0);//行
            int cellNum = row.getLastCellNum();
            Cell ce = null;

            for(int i = 1; i < lastNum + 1; i++){
                boolean isImport = true;
                row = sheet.getRow(i);
                for (int j = 0; j < cellNum; j++){
                    ce = row.getCell(j);
                    excelValuesList.add(getCellValueByCell(ce));
                }
                logger.info("writeDegree-excelValuesList:{}", excelValuesList);
                if(excelValuesList.size() > 0){
                    repeater = new Repeater();
                    if (excelValuesList.get(1) != null && !excelValuesList.get(1).equals("")) {
                        repeater.setAlias(excelValuesList.get(1));
                    }

                    if (excelValuesList.get(2) != null && !excelValuesList.get(2).equals("")) {
                        String serialNo = excelValuesList.get(2);
                        repeater.setSerialNo(serialNo);
                        List<Repeater> hasRepeater = authorityRepeaters.stream().filter(item -> item.getSerialNo().equals(serialNo)).collect(Collectors.toList());
                        if (hasRepeater == null || hasRepeater.size() == 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("SerialNo") + "," + languageFind.findKey("Device_Excel_IsNotExits_IsNotAuthority"));
                        }
                        if (serialNoList.contains(serialNo)) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("SerialNo") + "," + languageFind.findKey("Device_Excel_RepeatData_ImportFailure"));
                        }
                        serialNoList.add(serialNo);
                    } else {
                        isImport = false;
                        repeater.setImportErrorMessage(languageFind.findKey("SerialNo") + languageFind.findKey("Device_Excel_SerialNumberIsNotEmpty"));
                    }

                    if (!excelValuesList.get(3).toUpperCase().equals("E") && !excelValuesList.get(3).toUpperCase().equals("W")) {
                        repeater.setLngOr(2);
                        isImport = false;
                        repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_EastWestLng") + languageFind.findKey("Device_Excel_NotValidLngOr"));
                    } else {
                        repeater.setLngOr(excelValuesList.get(3).toUpperCase().equals("E") ? 0 : 1);
                        BigDecimal outLng = BigDecimal.ZERO;
                        if (!FileUtils.isBigDecimal(excelValuesList.get(4))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_Lng") + languageFind.findKey("Device_Excel_NotValidValue"));
                        } else {
                            outLng = new BigDecimal(excelValuesList.get(4)).abs();
                            repeater.setLng(BigDecimal.valueOf(repeater.getLngOr() == 0 ? 1 : -1).multiply(outLng));
                            if (outLng.compareTo(BigDecimal.ZERO) < 0 || outLng.compareTo(new BigDecimal(180)) > 0) {
                                isImport = false;
                                repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_Lng") + languageFind.findKey("Device_Excel_LngRange"));
                            } else {
                                BigDecimal[] longitudeDegreeMiuSec = getLongitudeDegreeMinuteSecond(repeater.getLng(), excelValuesList.get(3));
                                repeater.setLngDegreeMinuteSecond(longitudeDegreeMiuSec[0].abs() + "°" + longitudeDegreeMiuSec[1].abs() + "′" + longitudeDegreeMiuSec[2].abs() + "″");
                                repeater.setLngDegree(longitudeDegreeMiuSec[0]);
                                repeater.setLngMinute(longitudeDegreeMiuSec[1]);
                                repeater.setLngSecond(longitudeDegreeMiuSec[2]);
                            }
                        }
                    }

                    if (!excelValuesList.get(5).toUpperCase().equals("N") && !excelValuesList.get(5).toUpperCase().equals("S")) {
                        repeater.setLatOr(2);
                        isImport = false;
                        repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_SouthNorthLat") + languageFind.findKey("Device_Excel_NotValidLatOr"));
                    } else {
                        repeater.setLatOr(excelValuesList.get(5).toUpperCase().equals("N") ? 0 : 1);
                        BigDecimal outLat = BigDecimal.ZERO;
                        if (!FileUtils.isBigDecimal(excelValuesList.get(6))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_Lat") + languageFind.findKey("Device_Excel_NotValidValue"));
                        } else {
                            outLat = new BigDecimal(excelValuesList.get(6)).abs();
                            repeater.setLat(BigDecimal.valueOf(repeater.getLatOr() == 0 ? 1 : -1).multiply(outLat));
                            if (outLat.compareTo(BigDecimal.ZERO) < 0 || outLat.compareTo(new BigDecimal(90)) > 0) {
                                isImport = false;
                                repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_Lat") + languageFind.findKey("Device_Excel_LatRange"));
                            } else {
                                BigDecimal[] latitudeDegreeMiuSec = getLatitudeDegreeMinuteSecond(repeater.getLat(), excelValuesList.get(5));
                                repeater.setLatDegreeMinuteSecond(latitudeDegreeMiuSec[0].abs() + "°" + latitudeDegreeMiuSec[1].abs() + "′" + latitudeDegreeMiuSec[2].abs() + "″");
                                repeater.setLatDegree(latitudeDegreeMiuSec[0]);
                                repeater.setLatMinute(latitudeDegreeMiuSec[1]);
                                repeater.setLatSecond(latitudeDegreeMiuSec[2]);
                            }
                        }
                    }

                    if (excelValuesList.get(7) != null && !excelValuesList.get(7).equals("")) {
                        BigDecimal outElevation = BigDecimal.ZERO;
                        if (!FileUtils.isBigDecimal(excelValuesList.get(7))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_Elevation") + languageFind.findKey("Device_Excel_NotValidValue"));
                        } else {
                            outElevation = new BigDecimal(excelValuesList.get(7));
                            repeater.setElevation(outElevation);
                        }
                    } else {
                        repeater.setElevation(BigDecimal.ZERO);
                    }
                    if (isImport) {
                        repeaterList.add(repeater);
                    } else {
                        listError.add(repeater);
                    }
                }
                excelValuesList = new ArrayList<>();
            }
            inputStream.close();
            if (listError.size() > 0) {
                return ResponseModel.ofError(listError);
            } else {
                clientService.importRepeaterLngLat(repeaterList);
            }
        } catch (Exception e) {
            return ResponseModel.ofError(e.getMessage());
        }
        return ResponseModel.ofSuccess();
    }

    /**
     * 写入度分秒形式
     * @param file 文件
     * @return 结果
     */
    public ResponseModel writeDegreeMiuSec(MultipartFile file) {
        List<Repeater> repeaterList = new ArrayList<>();
        List<Repeater> listError = new ArrayList<>();
        Repeater repeater = null;
        List<String> excelValuesList = new ArrayList<>();
        List<String> serialNoList = new ArrayList<>();
        try {
            Account account = (Account) SecurityUtils.getSubject().getPrincipal();
            List<Repeater> authorityRepeaters = commonIClient.getAuthorityRepeaters(account.getUserName());
            String fileName = file.getOriginalFilename();
            InputStream inputStream = file.getInputStream();
            Workbook workbook = null;
            if (fileName.indexOf(".xlsx") > 0) {
                workbook = new XSSFWorkbook(inputStream);
            } else if (fileName.indexOf(".xls") > 0) {
                workbook = new HSSFWorkbook(inputStream);
            }
            Sheet sheet = workbook.getSheetAt(0);
            int lastNum = sheet.getLastRowNum();
            Row row = sheet.getRow(0);//行
            int cellNum = row.getLastCellNum();
            Cell ce = null;

            for(int i = 1; i < lastNum + 1; i++){
                boolean isImport = true;
                row = sheet.getRow(i);
                for (int j = 0; j < cellNum; j++){
                    ce = row.getCell(j);
                    excelValuesList.add(getCellValueByCell(ce));
                }
                logger.info("writeDegreeMiuSec-excelValuesList:{}", excelValuesList);
                if(excelValuesList.size() > 0){
                    repeater = new Repeater();
                    if (excelValuesList.get(1) != null && !excelValuesList.get(1).equals("")) {
                        repeater.setAlias(excelValuesList.get(1));
                    }

                    if (excelValuesList.get(2) != null && !excelValuesList.get(2).equals("")) {
                        String serialNo = excelValuesList.get(2);
                        repeater.setSerialNo(serialNo);
                        List<Repeater> hasRepeater = authorityRepeaters.stream().filter(item -> item.getSerialNo().equals(serialNo)).collect(Collectors.toList());
                        if (hasRepeater == null || hasRepeater.size() == 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("SerialNo") + "," + languageFind.findKey("Device_Excel_IsNotExits_IsNotAuthority"));
                        }
                        if (serialNoList.contains(serialNo)) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("SerialNo") + "," + languageFind.findKey("Device_Excel_RepeatData_ImportFailure"));
                        }
                        serialNoList.add(serialNo);
                    } else {
                        isImport = false;
                        repeater.setImportErrorMessage(languageFind.findKey("SerialNo") + languageFind.findKey("Device_Excel_SerialNumberIsNotEmpty"));
                    }

                    if (!excelValuesList.get(3).toUpperCase().equals("E") && !excelValuesList.get(3).toUpperCase().equals("W")) {
                        repeater.setLngOr(2);
                        isImport = false;
                        repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_EastWestLng") + languageFind.findKey("Device_Excel_NotValidLngOr"));
                    } else {
                        repeater.setLngOr(excelValuesList.get(3).toUpperCase().equals("E") ? 0 : 1);
                        BigDecimal outLngDegree = BigDecimal.ZERO;
                        BigDecimal outLngMinute = BigDecimal.ZERO;
                        BigDecimal outLngSecond = BigDecimal.ZERO;
                        if (!FileUtils.isBigDecimal(excelValuesList.get(4))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LngDegree") + languageFind.findKey("Device_Excel_NotValidValue"));
                        }
                        if (!FileUtils.isBigDecimal(excelValuesList.get(5))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LngMinute") + languageFind.findKey("Device_Excel_NotValidValue"));
                        }
                        if (!FileUtils.isBigDecimal(excelValuesList.get(6))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LngSecond") + languageFind.findKey("Device_Excel_NotValidValue"));
                        }

                        outLngDegree = new BigDecimal(excelValuesList.get(4)).abs();
                        outLngMinute = new BigDecimal(excelValuesList.get(5)).abs();
                        outLngSecond = new BigDecimal(excelValuesList.get(6)).abs();
                        repeater.setLngDegreeMinuteSecond(outLngDegree + "°" + outLngMinute + "′" + outLngSecond + "″");
                        repeater.setLngDegree(BigDecimal.valueOf(repeater.getLngOr() == 0 ? 1 : -1).multiply(outLngDegree));
                        repeater.setLngMinute(BigDecimal.valueOf(repeater.getLngOr() == 0 ? 1 : -1).multiply(outLngMinute));
                        repeater.setLngSecond(BigDecimal.valueOf(repeater.getLngOr() == 0 ? 1 : -1).multiply(outLngSecond));
                        if (outLngDegree.compareTo(BigDecimal.ZERO) < 0 || outLngDegree.compareTo(new BigDecimal(180)) > 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LngDegree") + languageFind.findKey("Device_Excel_LngDegreeRange"));
                        } else if (outLngMinute.compareTo(BigDecimal.ZERO) < 0 || outLngMinute.compareTo(new BigDecimal(60)) > 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LngMinute") + languageFind.findKey("Device_Excel_LngMinuteRange"));
                        } else if (outLngSecond.compareTo(BigDecimal.ZERO) < 0 || outLngSecond.compareTo(new BigDecimal(60)) > 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LngSecond") + languageFind.findKey("Device_Excel_LngSecondRange"));
                        } else {
                            BigDecimal lng = getLongitudeDegree(repeater.getLngDegree(), repeater.getLngMinute(), repeater.getLngSecond(), excelValuesList.get(3));
                            repeater.setLng(lng);
                        }
                    }

                    if (!excelValuesList.get(7).toUpperCase().equals("N") && !excelValuesList.get(7).toUpperCase().equals("S")) {
                        repeater.setLatOr(2);
                        isImport = false;
                        repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_SouthNorthLat") + languageFind.findKey("Device_Excel_NotValidLatOr"));
                    } else {
                        repeater.setLatOr(excelValuesList.get(7).toUpperCase().equals("N") ? 0 : 1);
                        BigDecimal outLatDegree = BigDecimal.ZERO;
                        BigDecimal outLatMinute = BigDecimal.ZERO;
                        BigDecimal outLatSecond = BigDecimal.ZERO;
                        if (!FileUtils.isBigDecimal(excelValuesList.get(8))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LatDegree") + languageFind.findKey("Device_Excel_NotValidValue"));
                        }
                        if (!FileUtils.isBigDecimal(excelValuesList.get(9))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LatMinute") + languageFind.findKey("Device_Excel_NotValidValue"));
                        }
                        if (!FileUtils.isBigDecimal(excelValuesList.get(10))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LatSecond") + languageFind.findKey("Device_Excel_NotValidValue"));
                        }
                        outLatDegree = new BigDecimal(excelValuesList.get(8)).abs();
                        outLatMinute = new BigDecimal(excelValuesList.get(9)).abs();
                        outLatSecond = new BigDecimal(excelValuesList.get(10)).abs();
                        repeater.setLatDegreeMinuteSecond(outLatDegree + "°" + outLatMinute + "′" + outLatSecond + "″");
                        repeater.setLatDegree(BigDecimal.valueOf(repeater.getLatOr() == 0 ? 1 : -1).multiply(outLatDegree));
                        repeater.setLatMinute(BigDecimal.valueOf(repeater.getLatOr() == 0 ? 1 : -1).multiply(outLatMinute));
                        repeater.setLatSecond(BigDecimal.valueOf(repeater.getLatOr() == 0 ? 1 : -1).multiply(outLatSecond));
                        if (outLatDegree.compareTo(BigDecimal.ZERO) < 0 || outLatDegree.compareTo(new BigDecimal(90)) > 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LatDegree") + languageFind.findKey("Device_Excel_LatDegreeRange"));
                        }
                        if (outLatMinute.compareTo(BigDecimal.ZERO) < 0 || outLatMinute.compareTo(new BigDecimal(90)) > 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LatMinute") + languageFind.findKey("Device_Excel_LatMinuteRange"));
                        }
                        if (outLatSecond.compareTo(BigDecimal.ZERO) < 0 || outLatSecond.compareTo(new BigDecimal(90)) > 0) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_LatSecond") + languageFind.findKey("Device_Excel_LatSecondRange"));
                        }
                        BigDecimal lat = getLatitudeDegree(repeater.getLatDegree(), repeater.getLatMinute(), repeater.getLatSecond(), excelValuesList.get(7));
                        repeater.setLat(lat);
                    }

                    if (excelValuesList.get(11) != null && !excelValuesList.get(11).equals("")) {
                        BigDecimal outElevation = BigDecimal.ZERO;
                        if (!FileUtils.isBigDecimal(excelValuesList.get(11))) {
                            isImport = false;
                            repeater.setImportErrorMessage(languageFind.findKey("Device_ExcelHeader_Elevation") + languageFind.findKey("Device_Excel_NotValidValue"));
                        } else {
                            outElevation = new BigDecimal(excelValuesList.get(11));
                            repeater.setElevation(outElevation);
                        }
                    } else {
                        repeater.setElevation(BigDecimal.ZERO);
                    }
                    if (isImport) {
                        repeaterList.add(repeater);
                    } else {
                        listError.add(repeater);
                    }
                }
                excelValuesList = new ArrayList<>();
            }
            inputStream.close();
            if (listError.size() > 0) {
                return ResponseModel.ofError(listError);
            } else {
                clientService.importRepeaterLngLat(repeaterList);
            }
        } catch (Exception e) {
            return ResponseModel.ofError(e.getMessage());
        }
        return ResponseModel.ofSuccess();
    }

    /**
     * 经度 -> 转度分秒
     * @param longitude 经度
     * @param enumLongitude 东西经
     * @return 结果
     */
    public BigDecimal[] getLongitudeDegreeMinuteSecond(BigDecimal longitude, String enumLongitude) {
        try {
            if (longitude.compareTo(BigDecimal.ZERO) == 0) {
                return new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO};
            }
            longitude = longitude.abs();
            BigDecimal degree = longitude.setScale(0, RoundingMode.DOWN);
            BigDecimal minute = longitude.subtract(degree).multiply(BigDecimal.valueOf(60)).setScale(0, RoundingMode.DOWN);
            BigDecimal second = longitude.subtract(degree).multiply(BigDecimal.valueOf(60)).subtract(minute).multiply(BigDecimal.valueOf(60)).setScale(1, RoundingMode.HALF_UP);
            if (enumLongitude.equals(EnumLongitudeLatitude.WEST.getValue())) {
                degree = degree.negate();
                minute = minute.negate();
                second = second.negate();
            }
            return new BigDecimal[]{degree, minute, second};
        } catch (Exception ex) {
            logger.error("GetLongitudeDegreeMinuteSecond> Exception:{}" + ex.getMessage());
            return new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO};
        }
    }

    /**
     * 纬度 -> 转度分秒
     * @param latitude 纬度
     * @param enumLatitude 南北纬
     * @return 结果
     */
    public BigDecimal[] getLatitudeDegreeMinuteSecond(BigDecimal latitude, String enumLatitude) {
        try {
            if (latitude.compareTo(BigDecimal.ZERO) == 0) {
                return new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO};
            }
            latitude = latitude.abs();
            BigDecimal degree = latitude.setScale(0, RoundingMode.DOWN);
            BigDecimal minute = latitude.subtract(degree).multiply(BigDecimal.valueOf(60)).setScale(0, RoundingMode.DOWN);
            BigDecimal second = latitude.subtract(degree).multiply(BigDecimal.valueOf(60)).subtract(minute).multiply(BigDecimal.valueOf(60)).setScale(1, RoundingMode.HALF_UP);

            if (enumLatitude.equals(EnumLongitudeLatitude.SOUTH.getValue())) {
                degree = degree.negate();
                minute = minute.negate();
                second = second.negate();
            }
            return new BigDecimal[]{degree, minute, second};
        } catch (Exception ex) {
            logger.error("getLatitudeDegreeMinuteSecond> Exception:{}" + ex.getMessage());
            return new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO};
        }
    }

    public String getCellValueByCell(Cell cell) {
        if (cell == null || cell.toString().trim().equals("")) {
            return "";
        }
        String cellValue = "";

        switch (cell.getCellType()) {
            case NUMERIC: //数字
                double numericValue = cell.getNumericCellValue();
                if (numericValue == Math.floor(numericValue)) {
                    // 如果是整数,直接转换为整数
                    cellValue = String.valueOf((int) numericValue);
                } else {
                    // 否则,使用 DecimalFormat 保留小数部分
                    DecimalFormat df = new DecimalFormat("#.##"); // 保留两位小数
                    cellValue = df.format(numericValue);
                }
                break;
            case STRING: //字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case BOOLEAN: //Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA: //公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case BLANK: //空值
                cellValue = "";
                break;
            case ERROR: //故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }

    /**
     * 度分秒 -> 转经度
     * @param degree 度
     * @param minute 分
     * @param second 秒
     * @param enumLongitude 东西经
     * @return 结果
     */
    public static BigDecimal getLongitudeDegree(BigDecimal degree, BigDecimal minute, BigDecimal second, String enumLongitude) {
        try {
            if (degree.compareTo(BigDecimal.ZERO) == 0 && minute.compareTo(BigDecimal.ZERO) == 0 && second.compareTo(BigDecimal.ZERO) == 0) {
                return BigDecimal.ZERO;
            }
            degree = degree.abs();
            minute = minute.abs();
            second = second.abs();
            BigDecimal lng = degree.add(minute.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : minute.divide(BigDecimal.valueOf(60), 8, RoundingMode.HALF_UP))
                    .add(second.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : second.divide(BigDecimal.valueOf(3600), 8, RoundingMode.HALF_UP)).setScale(8, RoundingMode.HALF_UP);
            if (enumLongitude.equals(EnumLongitudeLatitude.WEST.getValue())) {
                lng = lng.negate();
            }
            return lng;
        } catch (Exception ex) {
            logger.error("getLongitudeDegree> Exception:{}" + ex.getMessage());
            return BigDecimal.ZERO;
        }
    }

    /**
     * 度分秒 -> 转纬度
     * @param degree 度
     * @param minute 分
     * @param second 秒
     * @param enumLongitude 南北纬
     * @return 结果
     */
    public static BigDecimal getLatitudeDegree(BigDecimal degree, BigDecimal minute, BigDecimal second, String enumLongitude) {
        try {
            if (degree.compareTo(BigDecimal.ZERO) == 0 && minute.compareTo(BigDecimal.ZERO) == 0 && second.compareTo(BigDecimal.ZERO) == 0) {
                return BigDecimal.ZERO;
            }
            degree = degree.abs();
            minute = minute.abs();
            second = second.abs();
            BigDecimal lat = degree.add(minute.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : minute.divide(BigDecimal.valueOf(60), 8, RoundingMode.HALF_UP))
                    .add(second.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : second.divide(BigDecimal.valueOf(3600), 8, RoundingMode.HALF_UP)).setScale(8, RoundingMode.HALF_UP);
            if (enumLongitude.equals(EnumLongitudeLatitude.SOUTH.getValue())) {
                lat = lat.negate();
            }
            return lat;
        } catch (Exception ex) {
            logger.error("getLatitudeDegree> Exception:{}" + ex.getMessage());
            return BigDecimal.ZERO;
        }
    }

6.Repeater

package com.xnms.data.contract.database.db;

import org.apache.commons.lang3.builder.ToStringBuilder;

import javax.persistence.*;
import java.math.BigDecimal;

@Entity
@Table(name = "repeater")
public class Repeater {

    /// Repeater别名
    private String alias;

    /// 固件版本号
    private String firmwaveNo;

    /// rcdb版本号
    private String rcdbNo;

    /// RepeaterMachineNo
    @Transient
    private String machineNo;

    /// Repeater序列号信息
    private String serialNo;

    /// Repeater IP地址信息
    @Column(name = "IPADDRESS")
    private String ipAddress = "";

    /// Repeater snmpPort 端口:
    private Integer snmpPort = 0;

    @Transient
    private String siteAlias;

    /// Repeater站点所属信息
    /// 中转台在当前站点顺序
    private Integer siteIndex = 0;

    /// Repeater所属站点ID
    private Integer siteId = 0;

    /// 存储Repeater表唯一ID
    @Id
    private Integer repeaterId = 0;

    /// RadioID ID,中转台ID:
    private Integer radioId = 0;

    //在线状态【0:在线、1:离线】
    private Integer status = 0;

    /// (告警/离线/在线等状态)
    /// 增加中转台状态,用于拓扑地图根据状态是否显示告警图片,(告警/离线/在线等状态)
    @Transient
    private Integer rptState = 0;

    /// 用于在拓扑地图中标识,是否显示该中转台,默认全部显示,只用在勾选了check后才有选择显示
    @Transient
    private Integer rptChecked = 1;

    /// 中转台类型(语音/数据)
    /// 0、语音中转台
    /// 1、数据中转台
    private Integer type;

    /// 当前信道名称
    private String channelName = "";

    /// 当前发射频率
    private String currentTxFrequence = "";

    /// 当前接收频率
    private String currentRxFrequence = "";

    /// 系统类型
    /// 1:XPT
    /// 0:常规
    private Integer systemType;

    /// IP 互联
    private Integer ipConnectPort;

    /// 机器名称(RD980S)
    private String modelName;

    /// 机器编号(RD980-0000000S-000000-U1-0-C)
    private String modelNo;

    /// 当前工作模式
    /// 1、模拟模式
    /// 2、数字模式
    private String curMode;

    /// 中转台类型
    /// 0: Single Site(独立基站);
    /// 1: Master(主机);
    /// 2 : Slave(从机);
    /// 3 : Super Master(超级主机);
    /// 4: SubMaster(子网主机)
    private Integer repeaterSiteType;

    /// 中转台的主机IP地址
    private String masterIp;

    private String recursionMasterIp;

    /// 中转台主机端口
    private Integer masterPort;

    /// QDS IP
    private String serverIp;

    private String note1; //中转台备注
    private String note2; //中转台备注
    private String note3; //中转台备注

    private Integer deleted;

    /// 中转台接入码
    private String repeaterAccessCode;

    /// (真实)中转台接入码
    private String realAccessCode;

    /// 1、不同
    /// 0、相同
    @Transient
    private Integer accessCodeEqual;

    /// 导入文件序号
    @Transient
    private String importExcelXH;

    /// 导入时错误信息
    @Transient
    private String importErrorMessage;

    /// 经度
    private BigDecimal lng = BigDecimal.ZERO;

    /// 纬度
    private BigDecimal lat = BigDecimal.ZERO;

    /// 海拔
    private BigDecimal elevation = BigDecimal.ZERO;

    /// 0:东经
    /// 1:西经
    /// 2: 未知
    @Transient
    private Integer lngOr;

    /// 0:北纬
    /// 1:南纬
    /// 2:未知
    @Transient
    private Integer latOr;

    /// 经度(度分秒)
    @Transient
    private String lngDegreeMinuteSecond;

    /// 经度(度)
    private BigDecimal lngDegree;

    /// 经度(分)
    private BigDecimal lngMinute;

    /// 经度(秒)
    private BigDecimal lngSecond;

    /// 纬度(度分秒)
    @Transient
    private String latDegreeMinuteSecond;

    /// 纬度(度)
    private BigDecimal latDegree;

    /// 纬度(分)
    private BigDecimal latMinute;

    /// 纬度(秒)
    private BigDecimal latSecond;

    /// SNMP 版本
    private String repeaterSnmpVersion = "0";

    /// 中转台是否采用SNMPv3协议【0:否、1:是】
    @Column(name = "IS_SNMPV3")
    private String isSnmpV3 = "0";

    /// USM USER
    @Column(name = "SNMPV3_USM_USER")
    private String snmpV3UsmUser = "admin";

    /// 安全等级
    /// 0:no AUTH,no Priv
    /// 1:AUTH,no Priv
    /// 2:AUTH,Priv
    @Column(name = "SNMPV3_SECURITY_LEVEL")
    private String snmpV3SecurityLevel = "0";

    /// 鉴权
    /// 公钥类型,鉴权【None、MD5、SHA1】
    @Column(name = "SNMPV3_AUTH_ALGORITHM")
    private String snmpV3AuthAlgorithm = "None";

    /// 鉴权密码
    /// 公钥密码
    @Column(name = "SNMPV3_AUTH_PASSWORD")
    private String snmpV3AuthPassword;

    /// 加密
    /// 私钥类型,加密【None、DES、AES】
    @Column(name = "SNMPV3_PRIVACY_ALGORITHM")
    private String snmpV3PrivacyAlgorithm = "None";

    /// 加密密码
    /// 私钥密码
    @Column(name = "SNMPV3_PRIVACY_PASSWORD")
    private String snmpV3PrivacyPassword;

    /// 手填
    @Column(name = "SNMPV3_CONTEXT_NAME")
    private String snmpV3ContextName;

    @Transient
    private Integer Index;

    public Integer getIndex() {
        return Index;
    }

    public void setIndex(Integer index) {
        Index = index;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    public String getFirmwaveNo() {
        return firmwaveNo;
    }

    public void setFirmwaveNo(String firmwaveNo) {
        this.firmwaveNo = firmwaveNo;
    }

    public String getRcdbNo() {
        return rcdbNo;
    }

    public void setRcdbNo(String rcdbNo) {
        this.rcdbNo = rcdbNo;
    }

    public String getMachineNo() {
        return machineNo;
    }

    public void setMachineNo(String machineNo) {
        this.machineNo = machineNo;
    }

    public String getSerialNo() {
        return serialNo;
    }

    public void setSerialNo(String serialNo) {
        this.serialNo = serialNo;
    }

    public String getIpAddress() {
        return ipAddress;
    }

    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }

    public Integer getSnmpPort() {
        return snmpPort;
    }

    public void setSnmpPort(Integer snmpPort) {
        this.snmpPort = snmpPort;
    }

    public String getSiteAlias() {
        return siteAlias;
    }

    public void setSiteAlias(String siteAlias) {
        this.siteAlias = siteAlias;
    }

    public Integer getSiteIndex() {
        return siteIndex;
    }

    public void setSiteIndex(Integer siteIndex) {
        this.siteIndex = siteIndex;
    }

    public Integer getSiteId() {
        return siteId;
    }

    public void setSiteId(Integer siteId) {
        this.siteId = siteId;
    }

    public Integer getRepeaterId() {
        return repeaterId;
    }

    public void setRepeaterId(Integer repeaterId) {
        this.repeaterId = repeaterId;
    }

    public Integer getRadioId() {
        return radioId;
    }

    public void setRadioId(Integer radioId) {
        this.radioId = radioId;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Integer getRptState() {
        return rptState;
    }

    public void setRptState(Integer rptState) {
        this.rptState = rptState;
    }

    public Integer getRptChecked() {
        return rptChecked;
    }

    public void setRptChecked(Integer rptChecked) {
        this.rptChecked = rptChecked;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public String getChannelName() {
        return channelName;
    }

    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }

    public String getCurrentTxFrequence() {
        return currentTxFrequence;
    }

    public void setCurrentTxFrequence(String currentTxFrequence) {
        this.currentTxFrequence = currentTxFrequence;
    }

    public String getCurrentRxFrequence() {
        return currentRxFrequence;
    }

    public void setCurrentRxFrequence(String currentRxFrequence) {
        this.currentRxFrequence = currentRxFrequence;
    }

    public Integer getSystemType() {
        return systemType;
    }

    public void setSystemType(Integer systemType) {
        this.systemType = systemType;
    }

    public Integer getIpConnectPort() {
        return ipConnectPort;
    }

    public void setIpConnectPort(Integer ipConnectPort) {
        this.ipConnectPort = ipConnectPort;
    }

    public String getModelName() {
        return modelName;
    }

    public void setModelName(String modelName) {
        this.modelName = modelName;
    }

    public String getModelNo() {
        return modelNo;
    }

    public void setModelNo(String modelNo) {
        this.modelNo = modelNo;
    }

    public String getCurMode() {
        return curMode;
    }

    public void setCurMode(String curMode) {
        this.curMode = curMode;
    }

    public Integer getRepeaterSiteType() {
        return repeaterSiteType;
    }

    public void setRepeaterSiteType(Integer repeaterSiteType) {
        this.repeaterSiteType = repeaterSiteType;
    }

    public String getMasterIp() {
        return masterIp;
    }

    public void setMasterIp(String masterIp) {
        this.masterIp = masterIp;
    }

    public Integer getMasterPort() {
        return masterPort;
    }

    public void setMasterPort(Integer masterPort) {
        this.masterPort = masterPort;
    }

    public String getServerIp() {
        return serverIp;
    }

    public void setServerIp(String serverIp) {
        this.serverIp = serverIp;
    }

    public String getNote1() {
        return note1;
    }

    public void setNote1(String note1) {
        this.note1 = note1;
    }

    public String getNote2() {
        return note2;
    }

    public void setNote2(String note2) {
        this.note2 = note2;
    }

    public String getNote3() {
        return note3;
    }

    public void setNote3(String note3) {
        this.note3 = note3;
    }

    public Integer getDeleted() {
        return deleted;
    }

    public void setDeleted(Integer deleted) {
        this.deleted = deleted;
    }

    public String getRepeaterAccessCode() {
        return repeaterAccessCode;
    }

    public void setRepeaterAccessCode(String repeaterAccessCode) {
        this.repeaterAccessCode = repeaterAccessCode;
    }

    public String getRealAccessCode() {
        return realAccessCode;
    }

    public void setRealAccessCode(String realAccessCode) {
        this.realAccessCode = realAccessCode;
    }

    public Integer getAccessCodeEqual() {
        return accessCodeEqual;
    }

    public void setAccessCodeEqual(Integer accessCodeEqual) {
        this.accessCodeEqual = accessCodeEqual;
    }

    public String getImportExcelXH() {
        return importExcelXH;
    }

    public void setImportExcelXH(String importExcelXH) {
        this.importExcelXH = importExcelXH;
    }

    public String getImportErrorMessage() {
        return importErrorMessage;
    }

    public void setImportErrorMessage(String importErrorMessage) {
        this.importErrorMessage = importErrorMessage;
    }

    public BigDecimal getLng() {
        return lng;
    }

    public void setLng(BigDecimal lng) {
        this.lng = lng;
    }

    public BigDecimal getLat() {
        return lat;
    }

    public void setLat(BigDecimal lat) {
        this.lat = lat;
    }

    public BigDecimal getElevation() {
        return elevation;
    }

    public void setElevation(BigDecimal elevation) {
        this.elevation = elevation;
    }

    public Integer getLngOr() {
        return lngOr;
    }

    public void setLngOr(Integer lngOr) {
        this.lngOr = lngOr;
    }

    public Integer getLatOr() {
        return latOr;
    }

    public void setLatOr(Integer latOr) {
        this.latOr = latOr;
    }

    public String getLngDegreeMinuteSecond() {
        return lngDegreeMinuteSecond;
    }

    public void setLngDegreeMinuteSecond(String lngDegreeMinuteSecond) {
        this.lngDegreeMinuteSecond = lngDegreeMinuteSecond;
    }

    public BigDecimal getLngDegree() {
        return lngDegree;
    }

    public void setLngDegree(BigDecimal lngDegree) {
        this.lngDegree = lngDegree;
    }

    public BigDecimal getLngMinute() {
        return lngMinute;
    }

    public void setLngMinute(BigDecimal lngMinute) {
        this.lngMinute = lngMinute;
    }

    public BigDecimal getLngSecond() {
        return lngSecond;
    }

    public void setLngSecond(BigDecimal lngSecond) {
        this.lngSecond = lngSecond;
    }

    public String getLatDegreeMinuteSecond() {
        return latDegreeMinuteSecond;
    }

    public void setLatDegreeMinuteSecond(String latDegreeMinuteSecond) {
        this.latDegreeMinuteSecond = latDegreeMinuteSecond;
    }

    public BigDecimal getLatDegree() {
        return latDegree;
    }

    public void setLatDegree(BigDecimal latDegree) {
        this.latDegree = latDegree;
    }

    public BigDecimal getLatMinute() {
        return latMinute;
    }

    public void setLatMinute(BigDecimal latMinute) {
        this.latMinute = latMinute;
    }

    public BigDecimal getLatSecond() {
        return latSecond;
    }

    public void setLatSecond(BigDecimal latSecond) {
        this.latSecond = latSecond;
    }

    public String getRepeaterSnmpVersion() {
        return repeaterSnmpVersion;
    }

    public void setRepeaterSnmpVersion(String repeaterSnmpVersion) {
        this.repeaterSnmpVersion = repeaterSnmpVersion;
    }

    public String getIsSnmpV3() {
        return isSnmpV3;
    }

    public void setIsSnmpV3(String isSnmpV3) {
        this.isSnmpV3 = isSnmpV3;
    }

    public String getSnmpV3UsmUser() {
        return snmpV3UsmUser;
    }

    public void setSnmpV3UsmUser(String snmpV3UsmUser) {
        this.snmpV3UsmUser = snmpV3UsmUser;
    }

    public String getSnmpV3SecurityLevel() {
        return snmpV3SecurityLevel;
    }

    public void setSnmpV3SecurityLevel(String snmpV3SecurityLevel) {
        this.snmpV3SecurityLevel = snmpV3SecurityLevel;
    }

    public String getSnmpV3AuthAlgorithm() {
        return snmpV3AuthAlgorithm;
    }

    public void setSnmpV3AuthAlgorithm(String snmpV3AuthAlgorithm) {
        this.snmpV3AuthAlgorithm = snmpV3AuthAlgorithm;
    }

    public String getSnmpV3AuthPassword() {
        return snmpV3AuthPassword;
    }

    public void setSnmpV3AuthPassword(String snmpV3AuthPassword) {
        this.snmpV3AuthPassword = snmpV3AuthPassword;
    }

    public String getSnmpV3PrivacyAlgorithm() {
        return snmpV3PrivacyAlgorithm;
    }

    public void setSnmpV3PrivacyAlgorithm(String snmpV3PrivacyAlgorithm) {
        this.snmpV3PrivacyAlgorithm = snmpV3PrivacyAlgorithm;
    }

    public String getSnmpV3PrivacyPassword() {
        return snmpV3PrivacyPassword;
    }

    public void setSnmpV3PrivacyPassword(String snmpV3PrivacyPassword) {
        this.snmpV3PrivacyPassword = snmpV3PrivacyPassword;
    }

    public String getSnmpV3ContextName() {
        return snmpV3ContextName;
    }

    public void setSnmpV3ContextName(String snmpV3ContextName) {
        this.snmpV3ContextName = snmpV3ContextName;
    }

    public String getRecursionMasterIp() {
        return recursionMasterIp;
    }

    public void setRecursionMasterIp(String recursionMasterIp) {
        this.recursionMasterIp = recursionMasterIp;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

}

7.FileUtils

package com.xnms.client.service.utils;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigDecimal;

public class FileUtils {

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


    /**
     * 获取文件后缀扩展名
     * @param fileName 文件名
     * @return 结果
     */
    public static String getFileExtension(String fileName) {
        int index = fileName.lastIndexOf(".");
        if (index > 0 && index < fileName.length() - 1) {
            return fileName.substring(index);
        }
        return "";
    }

    /**
     * 获取excel的列数
     * @param file 文件
     * @return 结果
     */
    public static int getExcelColumnCount(MultipartFile file) {
        int columnCount = 0;
        String fileName = file.getOriginalFilename();
        Workbook workbook = null;
        try {
            InputStream inputStream = file.getInputStream();
            if (fileName.indexOf(".xlsx") > 0) {
                workbook = new XSSFWorkbook(inputStream);
            } else if (fileName.indexOf(".xls") > 0) {
                workbook = new HSSFWorkbook(inputStream);
            }
            Sheet sheet = workbook.getSheetAt(0);
            Row firstRow = sheet.getRow(0);
            if (firstRow != null) {
                columnCount = firstRow.getPhysicalNumberOfCells();
            }
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("getExcelColumnCount-Exception:{}", e.getMessage());
        }
        return columnCount;
    }

    /**
     * 校验字符串数值是否是BigDecimal类型
     * @param str 字符串数值
     * @return 结果
     */
    public static boolean isBigDecimal(String str) {
        try {
            new BigDecimal(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

8.ResponseModel

package com.xnms.client.service.controller.common;

import com.xnms.data.contract.database.db.Pagination;

public class ResponseModel<T> {

    private int code;           // 状态码,表示请求是否成功
    private String msg;         // 信息,通常用于描述错误或操作成功的提示
    private T data;             // 数据,通常是请求返回的具体内容
    private Pagination pagination;  // 分页参数,封装分页相关的数据

    // 私有构造函数
    private ResponseModel(int code, String msg, T data, Pagination pagination) {
        this.code = code;
        this.msg = msg;
        this.data = data;
        this.pagination = pagination;
    }

    // 默认构造函数
    private ResponseModel() {
        this.code = ConstantsCode.HTTP_OK;           // 默认 code 为 200
        this.msg = "成功";         // 默认 msg 为 "成功"
        this.pagination = null;    // 默认 pagination 为 null
    }

    // 静态方法:只返回数据和分页信息
    public static <T> ResponseModel<T> of(T data, Pagination pagination) {
        ResponseModel<T> response = new ResponseModel<>();
        response.setData(data);
        response.setPagination(pagination);
        return response;
    }

    // 静态方法:返回数据和分页信息,默认成功信息
    public static <T> ResponseModel<T> ofSuccess(T data, Pagination pagination) {
        return new ResponseModel<>(ConstantsCode.HTTP_OK, "成功", data, pagination);
    }

    public static <T> ResponseModel<T> ofSuccess(T data, String msg, Pagination pagination) {
        return new ResponseModel<>(ConstantsCode.HTTP_OK, msg, data, pagination);
    }

    // 静态方法:返回数据和成功信息,分页信息为空
    public static <T> ResponseModel<T> ofSuccess(T data) {
        return new ResponseModel<>(ConstantsCode.HTTP_OK, "成功", data, null);
    }

    public static <T> ResponseModel<T> ofSuccess() {
        return new ResponseModel<>(ConstantsCode.HTTP_OK, "成功", null, null);
    }

    public static <T> ResponseModel<T> ofError(T data) {
        return new ResponseModel<>(ConstantsCode.HTTP_INTERNAL_SERVER_ERROR, "失败", data, null);
    }

    // 静态方法:返回错误信息
    public static <T> ResponseModel<T> ofError(String msg) {
        return new ResponseModel<>(ConstantsCode.HTTP_INTERNAL_SERVER_ERROR, msg, null, null);
    }

    public static <T> ResponseModel<T> ofError(int code, String msg) {
        return new ResponseModel<>(code, msg, null, null);
    }

    // 静态方法:只返回分页信息,数据为空
    public static <T> ResponseModel<T> ofPagination(Pagination pagination) {
        return new ResponseModel<>(ConstantsCode.HTTP_OK, "成功", null, pagination);
    }

    // 静态方法:无数据,无分页,仅返回状态码和信息
    public static <T> ResponseModel<T> ofStatus(int code, String msg) {
        return new ResponseModel<>(code, msg, null, null);
    }

    // Getter 和 Setter 方法
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Pagination getPagination() {
        return pagination;
    }

    public void setPagination(Pagination pagination) {
        this.pagination = pagination;
    }

}

9.EnumLongitudeLatitude

package com.xnms.client.service.Utility;

//经纬度枚举
public enum EnumLongitudeLatitude {

    NORTH("N"),
    SOUTH("S"),
    EAST("E"),
    WEST("W"),
    UnKnown("");

    private String value;

    public String getValue() {

        return value;
    }

    EnumLongitudeLatitude(String value) {
        this.value = value;
    }
}

10.词条

CauseOfImportFailure=导入失败原因
ImportFailedData=导入数据失败
Device_ExcelHeader_No=序号
Device_ExcelHeader_Alias=别名
Device_ExcelHeader_SerialNumber=序列号
Device_ExcelHeader_EastWestLng=东西经
Device_ExcelHeader_Lng=经度
Device_ExcelHeader_SouthNorthLat=南北纬
Device_ExcelHeader_Lat=纬度
Device_ExcelHeader_Elevation=海拔
Device_ExcelHeader_LngDegree=经度()
Device_ExcelHeader_LngMinute=经度()
Device_ExcelHeader_LngSecond=经度()
Device_ExcelHeader_LatDegree=纬度()
Device_ExcelHeader_LatMinute=纬度()
Device_ExcelHeader_LatSecond=纬度()
Device_Excel_ColumnIsInUse=文件被占用
Device_Excel_ColumnIsNotExits=模板格式错误
Device_Excel_SerialNumberIsNotEmpty=不能为空
Device_Excel_IsNotExits_IsNotAuthority=不存在或没有权限
Device_Excel_NotValidValue=不是有效数值
Device_Excel_NotValidLngOr=值为EW
Device_Excel_NotValidLatOr=值为SN
Device_Excel_LngRange=超出经度范围0-180
Device_Excel_LngDegreeRange=超出经度()范围 0-180
Device_Excel_LngMinuteRange=超出经度()范围 0-60
Device_Excel_LngSecondRange=超出经度()范围 0-60
Device_Excel_LatRange=超出纬度范围0-90
Device_Excel_LatDegreeRange=超出纬度()范围 0-90
Device_Excel_LatMinuteRange=超出纬度()范围 0-60
Device_Excel_LatSecondRange=超出纬度()范围 0-60
Device_Excel_RepeatData_ImportFailure=重复数据,导入失败.
Device_Excel_RepeatData_1000MaximumData=最大数据1000Device_Excel_DataNotAllowedToImport=未找到可以导入的数据

四、注意点

注意点1:页面设备管理哪里可以直接手动修改经纬度和高海拔,该设计是考虑当你想单一修改个别设备时可以直接修改保存,而无需导入excel去修改。

注意点2:点击“导入”按钮时可以看到,允许下载2套不同模版。

注意点3:导入excel如果校验成功,则直接弹窗提示“导入成功”,或者其他词条;而有部分校验失败的地方则展示所有错误信息,方便精确知道哪行信息未通过。

注意点4: 上传经纬度(度数)excel时同步更新度、分、秒字段;同理上传经纬度(度分秒)excel时同步更新经纬度字段;因为实体有字段会动态拼接“度数字符串”和“度分秒字符串”返回前端进行展示。
在这里插入图片描述

注意点5:

  • 经度 -> 转度分秒 => 对应方法getLongitudeDegreeMinuteSecond()
  • 纬度 -> 转度分秒 => 对应方法getLatitudeDegreeMinuteSecond()
  • 度分秒 -> 转经度 => 对应方法getLongitudeDegree()
  • 度分秒 -> 转纬度 => 对应方法getLatitudeDegree()

本人其他相关文章链接

1.vue3 开发电子地图功能
2.vue java 实现大地图切片上传
3.java导入excel更新设备经纬度度数或者度分秒
4.快速上手Vue3国际化 (i18n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频设备轨迹回放平台EasyCVR远程监控体系落地筑牢国土监管防线

一、背景概述 我国土地资源遭违法滥用的现象愈发严峻&#xff0c;各类土地不合理利用问题频发。不当的土地开发不仅加剧了地质危害风险&#xff0c;导致良田受损、森林资源的滥伐&#xff0c;还引发了煤矿无序开采、城市开发区违建等乱象&#xff0c;给国家宝贵的土地资源造成…

Stable Diffusion 四重调参优化——项目学习记录

学习记录还原&#xff1a;在本次实验中&#xff0c;我基于 Stable Diffusion v1.5模型&#xff0c;通过一系列优化方法提升生成图像的质量&#xff0c;最终实现了图像质量的显著提升。实验从基础的 Img2Img 技术入手&#xff0c;逐步推进到参数微调、DreamShaper 模型和 Contro…

我可能用到的网站和软件

我可能用到的网站和软件 程序员交流的网站代码管理工具前端组件库前端框架在线工具人工智能问答工具学习的网站Windows系统电脑的常用工具 程序员交流的网站 csdn博客博客园 - 开发者的网上家园InfoQ - 软件开发及相关领域-极客邦掘金 (juejin.cn) 代码管理工具 GitHub 有时…

FPGA状态机设计:流水灯实现、Modelsim仿真、HDLBits练习

一、状态机思想 1.概念 状态机&#xff08;Finite State Machine, FSM&#xff09;是计算机科学和工程领域中的一种抽象模型&#xff0c;用于描述系统在不同状态之间的转换逻辑。其核心思想是将复杂的行为拆解为有限的状态&#xff0c;并通过事件触发状态间的转移。 2.状态机…

2024年第十五届蓝桥杯CC++大学A组--成绩统计

2024年第十五届蓝桥杯C&C大学A组--成绩统计 题目&#xff1a; 动态规划&#xff0c; 对于该题&#xff0c;考虑动态规划解法&#xff0c;先取前k个人的成绩计算其方差&#xff0c;并将成绩记录在数组中&#xff0c;记录当前均值&#xff0c;设小蓝已检查前i-1个人的成绩&…

Kotlin 学习-集合

/*** kotlin 集合* List:是一个有序列表&#xff0c;可通过索引&#xff08;下标&#xff09;访问元素。元素可以在list中出现多次、元素可重复* Set:是元素唯一的集合。一般来说 set中的元素顺序并不重要、无序集合* Map:&#xff08;字典&#xff09;是一组键值对。键是唯一的…

自动驾驶的未来:多模态感知融合技术最新进展

作为自动驾驶领域的专业人士&#xff0c;我很高兴与大家分享关于多模态感知融合技术的前沿研究和实践经验。在迅速发展的自动驾驶领域&#xff0c;多模态感知融合已成为提升系统性能的关键技术。本文将深入探讨基于摄像头和激光雷达的多模态感知融合技术&#xff0c;重点关注最…

亮相2025全球分布式云大会,火山引擎边缘云落地AI新场景

4 月 9 日&#xff0c;2025 全球分布式云大会暨 AI 基础设施大会在深圳成功举办&#xff0c;火山引擎边缘云产品解决方案高级总监沈建发出席并以《智启边缘&#xff0c;畅想未来&#xff1a;边缘计算新场景落地与 Al 趋势新畅想》为主题&#xff0c;分享了边缘计算在 AI 技术趋…

无损分区管理,硬盘管理的“瑞士军刀”!

打工人们你们好&#xff01;这里是摸鱼 特供版~ 今天给大家带来一款简单易用、功能强大的无损分区软件——分区助手技术员版&#xff0c;让你的硬盘管理变得轻松又高效&#xff01; 推荐指数&#xff1a;★★★★★ 软件简介 分区助手技术员版是一款功能强大的硬盘分区工具&…

VS Code下开发FPGA——FPGA开发体验提升__下

上一篇&#xff1a;IntelliJ IDEA下开发FPGA-CSDN博客 Type&#xff1a;Quartus 一、安装插件 在应用商店先安装Digtal IDE插件 安装后&#xff0c;把其他相关的Verilog插件禁用&#xff0c;避免可能的冲突。重启后&#xff0c;可能会弹出下面提示 这是插件默认要求的工具链&a…

ffmpeg播放音视频流程

文章目录 &#x1f3ac; FFmpeg 解码播放流程概览&#xff08;以音视频文件为例&#xff09;1️⃣ 创建结构体2️⃣ 打开音视频文件3️⃣ 查找解码器并打开解码器4️⃣ 循环读取数据包&#xff08;Packet&#xff09;5️⃣ 解码成帧&#xff08;Frame&#xff09;6️⃣ 播放 / …

SpringCloud微服务: 分布式架构实战

# SpringCloud微服务: 分布式架构实战 第一章&#xff1a;理解SpringCloud微服务架构 什么是SpringCloud微服务架构&#xff1f; 在当今互联网应用开发中&#xff0c;微服务架构已经成为业界的主流趋势。SpringCloud是一个基于Spring Boot的快速开发微服务架构的工具&#xff0…

AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年4月11日第49弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀6-8个和值&#xff0c;可以做到100-300注左右。 (1)定…

【models】Transformer 之 各种 Attention 原理和实现

Transformer 之 各种 Attention 原理和实现 本文将介绍Transformer 中常见的Attention的原理和实现&#xff0c;其中包括&#xff1a; Self Attention、Spatial Attention、Temporal Attention、Cross Attention、Grouped Attention、Tensor Product Attention、FlashAttentio…

老硬件也能运行的Win11 IoT LTSC (OEM)物联网版

#记录工作 Windows 11 IoT Enterprise LTSC 2024 属于物联网相关的版本。 Windows 11 IoT Enterprise 是为物联网设备和场景设计的操作系统版本。它通常针对特定的工业控制、智能设备等物联网应用进行了优化和定制&#xff0c;以满足这些领域对稳定性、安全性和长期支持的需求…

Git开发

目录 Linux下Git安装Git基本指令分支管理远程仓库与本地仓库标签管理多人协作同一分支下不同分支下 企业级开发模型 -- git flow 模型 在现实中&#xff0c;当我们完成一个文档的初稿后&#xff0c;后面可能还需要对初稿进行反复修改&#xff0c;从而形成不同版本的文档。显然&…

verilog有符号数的乘法

无符号整数的乘法 1、单周期乘法器&#xff08; 无符号整数 &#xff09; 对于低速要求的乘法器&#xff0c;可以简单的使用 * 实现。 module Mult(input wire [7:0] multiplicand ,input wire [7:0] multipliter ,output wire [7:0] product);as…

DevDocs:抓取并整理技术文档的MCP服务

GitHub&#xff1a;https://github.com/cyberagiinc/DevDocs 更多AI开源软件&#xff1a;发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI DevDocs 是一个完全免费的开源工具&#xff0c;由 CyberAGI 团队开发&#xff0c;托管在 GitHub 上。它专为程序员和软件开发…

第十四届蓝桥杯大赛软件赛国赛Python大学B组题解

文章目录 弹珠堆放划分偶串交易账本背包问题翻转最大阶梯最长回文前后缀贸易航线困局 弹珠堆放 递推式 a i a i − 1 i a_ia_{i-1}i ai​ai−1​i&#xff0c; n 20230610 n20230610 n20230610非常小&#xff0c;直接模拟 答案等于 494 494 494 划分 因为总和为 1 e 6 1e6…

折叠屏手机:技术进步了,柔性OLED面板测试技术需求跟上了吗?

全球智能手机市场陷入创新焦虑&#xff0c;折叠屏手机被寄予厚望&#xff0c;2023 年出货量同比增长 62%。但在供应链技术狂欢背后&#xff0c;存在诸多问题。消费端数据显示&#xff0c;用户使用频率低&#xff0c;定价策略反常。产业链重构虽让部分企业获利&#xff0c;却推高…