Ver Fonte

feat: 实现车辆报告定时任务

weijianghai há 9 meses atrás
pai
commit
8bcd21833c
100 ficheiros alterados com 14419 adições e 13 exclusões
  1. 4 0
      .mvn/maven.config
  2. 26 1
      pom.xml
  3. 10 0
      readme.md
  4. 3 2
      src/main/java/com/nokia/finance/tasks/common/utils/psql/PsqlUtil.java
  5. 103 0
      src/main/java/com/nokia/finance/tasks/config/CarReportConfig.java
  6. 62 0
      src/main/java/com/nokia/finance/tasks/config/HttpClientConfig.java
  7. 50 0
      src/main/java/com/nokia/finance/tasks/config/MinioConfig.java
  8. 464 0
      src/main/java/com/nokia/finance/tasks/dao/car/CarProcedureDao.java
  9. 1292 0
      src/main/java/com/nokia/finance/tasks/dao/car/CarReportDao.java
  10. 4 0
      src/main/java/com/nokia/finance/tasks/enums/JobEnum.java
  11. 310 0
      src/main/java/com/nokia/finance/tasks/jobs/car/CarReportJob.java
  12. 3 0
      src/main/java/com/nokia/finance/tasks/jobs/car/procedure/CarFeeProcJob.java
  13. 27 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarBglryQsPo.java
  14. 31 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarBglryUnitPo.java
  15. 29 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarBszsbPo.java
  16. 43 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarClgkPo.java
  17. 41 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarCqclqkPo.java
  18. 143 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarDxPo.java
  19. 43 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarDxUnitPo.java
  20. 58 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarJygxPo.java
  21. 39 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarJygxUnitPo.java
  22. 44 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarNoticesPo.java
  23. 21 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarReportsPo.java
  24. 92 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarRyycPo.java
  25. 15 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarRyycUnitPo.java
  26. 61 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarSnfyPo.java
  27. 93 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWgPo.java
  28. 19 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWxQsPo.java
  29. 31 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWxUnitPo.java
  30. 89 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWzPo.java
  31. 15 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWzUnitPo.java
  32. 80 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarZlwxycPo.java
  33. 80 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarZywxycPo.java
  34. 15 0
      src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarZywxycUnitPo.java
  35. 18 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarBglryQsVo.java
  36. 23 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarBglryUnitVo.java
  37. 23 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarBszsbVo.java
  38. 172 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarCldxVo.java
  39. 159 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarClfyVo.java
  40. 243 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarClgkVo.java
  41. 82 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarCqclqkVo.java
  42. 84 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarDxUnitVo.java
  43. 65 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarJygxUnitVo.java
  44. 65 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarReportVo.java
  45. 21 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarRyycUnitVo.java
  46. 82 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarSnfyVo.java
  47. 23 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWgUnitVo.java
  48. 149 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWgycVo.java
  49. 18 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWxQsVo.java
  50. 23 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWxUnitVo.java
  51. 21 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWzUnitVo.java
  52. 145 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWzclycVo.java
  53. 149 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarYcryfVo.java
  54. 93 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZlwxycVo.java
  55. 35 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZlycwxVo.java
  56. 21 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZywxycUnitVo.java
  57. 147 0
      src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZyycwxVo.java
  58. 5 1
      src/main/java/com/nokia/finance/tasks/service/JobService.java
  59. 3 3
      src/main/java/com/nokia/finance/tasks/service/car/CarService.java
  60. 79 0
      src/main/java/com/nokia/finance/tasks/service/common/file/FileService.java
  61. 118 0
      src/main/java/com/nokia/finance/tasks/service/common/file/MinioServiceImpl.java
  62. 60 0
      src/main/java/com/nokia/finance/tasks/utils/OfficeUtil.java
  63. 35 0
      src/main/java/com/nokia/finance/tasks/utils/ZipUtil.java
  64. 62 6
      src/main/resources/application-dev.yml
  65. 54 0
      src/main/resources/application-prod.yml
  66. 26 0
      src/test/java/com/nokia/finance/tasks/MybatisPlusGeneratorTest.java
  67. 21 0
      src/test/java/com/nokia/finance/tasks/car/CarReportJobTests.java
  68. 1 0
      templates/car/report/docx/[Content_Types].xml
  69. 2 0
      templates/car/report/docx/_rels/.rels
  70. 2 0
      templates/car/report/docx/customXml/_rels/item1.xml.rels
  71. 1 0
      templates/car/report/docx/customXml/item1.xml
  72. 2 0
      templates/car/report/docx/customXml/itemProps1.xml
  73. 19 0
      templates/car/report/docx/docProps/app.xml
  74. 12 0
      templates/car/report/docx/docProps/core.xml
  75. 2 0
      templates/car/report/docx/docProps/custom.xml
  76. 1 0
      templates/car/report/docx/word/_rels/document.xml.rels
  77. 290 0
      templates/car/report/docx/word/charts/chart1.xml
  78. 304 0
      templates/car/report/docx/word/charts/chart2.xml
  79. 314 0
      templates/car/report/docx/word/charts/chart3.xml
  80. 286 0
      templates/car/report/docx/word/charts/chart4.xml
  81. 314 0
      templates/car/report/docx/word/charts/chart5.xml
  82. 7099 0
      templates/car/report/docx/word/document.xml
  83. BIN
      templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet.xlsx
  84. BIN
      templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet1.xlsx
  85. BIN
      templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet2.xlsx
  86. BIN
      templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet3.xlsx
  87. BIN
      templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet4.xlsx
  88. BIN
      templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet5.xlsx
  89. 1 0
      templates/car/report/docx/word/fontTable.xml
  90. BIN
      templates/car/report/docx/word/media/image1.png
  91. BIN
      templates/car/report/docx/word/media/image2.emf
  92. BIN
      templates/car/report/docx/word/media/image3.emf
  93. BIN
      templates/car/report/docx/word/media/image4.emf
  94. BIN
      templates/car/report/docx/word/media/image5.emf
  95. BIN
      templates/car/report/docx/word/media/image6.emf
  96. BIN
      templates/car/report/docx/word/media/image7.emf
  97. 1 0
      templates/car/report/docx/word/settings.xml
  98. 1 0
      templates/car/report/docx/word/styles.xml
  99. 1 0
      templates/car/report/docx/word/theme/theme1.xml
  100. 2 0
      templates/car/report/docx/word/webSettings.xml

+ 4 - 0
.mvn/maven.config

@@ -0,0 +1,4 @@
+-U
+-T1C
+-Dmaven.test.skip=true
+-Dmaven.compile.fork=true

+ 26 - 1
pom.xml

@@ -52,7 +52,7 @@
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-exec</artifactId>
-            <version>1.3</version>
+            <version>1.4.0</version>
         </dependency>
         <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
         <dependency>
@@ -105,6 +105,31 @@
             <artifactId>commons-lang3</artifactId>
             <version>3.14.0</version>
         </dependency>
+        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>1.26.1</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/io.minio/minio -->
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+            <version>8.5.10</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+            <version>1.12.0</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.5.6</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <dependencyManagement>

+ 10 - 0
readme.md

@@ -201,3 +201,13 @@ curl --location 'http://127.0.0.1:39110/jobs/runJob' \
     "jobName": "HOUSE_RENT_IN_REPAIR_MONTH_JOB"
 }'
 ```
+
+##### 车辆报告定时任务
+
+```shell
+curl --location 'http://127.0.0.1:39110/jobs/runJob' \
+--header 'Content-Type: application/json' \
+--data '{
+    "jobName": "CAR_REPORT_JOB"
+}'
+```

+ 3 - 2
src/main/java/com/nokia/finance/tasks/common/utils/psql/PsqlUtil.java

@@ -9,6 +9,7 @@ import org.apache.commons.exec.PumpStreamHandler;
 import org.springframework.util.StringUtils;
 
 import java.io.ByteArrayOutputStream;
+import java.time.Duration;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -53,8 +54,8 @@ public class PsqlUtil {
         log.info("command: {}", commandLine);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         ByteArrayOutputStream err = new ByteArrayOutputStream();
-        DefaultExecutor executor = new DefaultExecutor();
-        ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
+        DefaultExecutor executor = DefaultExecutor.builder().get();
+        ExecuteWatchdog watchdog = ExecuteWatchdog.builder().setTimeout(Duration.ofMinutes(timeout)).get();
         executor.setWatchdog(watchdog);
         PumpStreamHandler streamHandler = new PumpStreamHandler(out, err);
         executor.setStreamHandler(streamHandler);

+ 103 - 0
src/main/java/com/nokia/finance/tasks/config/CarReportConfig.java

@@ -0,0 +1,103 @@
+package com.nokia.finance.tasks.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Data
+@Configuration
+@ConfigurationProperties("car-report")
+public class CarReportConfig {
+    /**
+     * docx文件夹
+     */
+    private String docxDir;
+    /**
+     * 输出路径
+     */
+    private String outDir;
+    /**
+     * 输出docx路径
+     */
+    private String docx;
+    /**
+     * 输出pdf路径
+     */
+    private String pdf;
+    /**
+     * ftl文件夹
+     */
+    private String ftlDir;
+    /**
+     * document ftl路径
+     */
+    private String documentFtl;
+    /**
+     * 北十车辆费用占收比对标图表ftl路径
+     */
+    private String bszsbChartFtl;
+    /**
+     * 1-12月百公里燃油费变化情况图表ftl路径
+     */
+    private String bglryQsChartFtl;
+    /**
+     * 二级组织机构百公里燃油图表ftl路径
+     */
+    private String bglryUnitChartFtl;
+    /**
+     * 1-12月维修费变化情况图表ftl路径
+     */
+    private String wxQsChartFtl;
+    /**
+     * 二级组织机构自有车辆单车维修费图表ftl路径
+     */
+    private String wxUnitChartFtl;
+    /**
+     * document xml路径
+     */
+    private String documentXml;
+    /**
+     * 北十车辆费用占收比对标图表xml路径
+     */
+    private String bszsbChartXml;
+    /**
+     * 1-12月百公里燃油费变化情况图表xml路径
+     */
+    private String bglryQsChartXml;
+    /**
+     * 二级组织机构百公里燃油图表xml路径
+     */
+    private String bglryUnitChartXml;
+    /**
+     * 1-12月维修费变化情况图表xml路径
+     */
+    private String wxQsChartXml;
+    /**
+     * 二级组织机构自有车辆单车维修费图表xml路径
+     */
+    private String wxUnitChartXml;
+    /**
+     * 建议更新车辆xlsx路径
+     */
+    private String jygxXlsx;
+    /**
+     * 燃油异常xlsx路径
+     */
+    private String ryycXlsx;
+    /**
+     * 自有车辆异常维修费xlsx路径
+     */
+    private String zywxycXlsx;
+    /**
+     * 低效车辆xlsx路径
+     */
+    private String dxXlsx;
+    /**
+     * 违规用车xlsx路径
+     */
+    private String wgXlsx;
+    /**
+     * 违章xlsx路径
+     */
+    private String wzXlsx;
+}

+ 62 - 0
src/main/java/com/nokia/finance/tasks/config/HttpClientConfig.java

@@ -0,0 +1,62 @@
+package com.nokia.finance.tasks.config;
+
+import okhttp3.OkHttpClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+
+/**
+ * OKHttpClient配置
+ */
+@Configuration
+public class HttpClientConfig {
+    @Bean
+    public OkHttpClient myHttpClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
+        return new OkHttpClient.Builder()
+                .hostnameVerifier((hostname, session) -> true)
+                .retryOnConnectionFailure(true)
+                .sslSocketFactory(getSslSocketFactory(), getX509TrustManager())
+                .build();
+    }
+
+    private SSLSocketFactory getSslSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
+        SSLContext sslContext = SSLContext.getInstance("SSL");
+        sslContext.init(null, new TrustManager[]{
+                new X509TrustManager() {
+                    @Override
+                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
+                        // 不检查证书
+                    }
+
+                    @Override
+                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
+                        // 不检查证书
+                    }
+
+                    @Override
+                    public X509Certificate[] getAcceptedIssuers() {
+                        return new X509Certificate[]{};
+                    }
+                }
+        }, new SecureRandom());
+        return sslContext.getSocketFactory();
+    }
+
+    private X509TrustManager getX509TrustManager() throws NoSuchAlgorithmException, KeyStoreException {
+        TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        factory.init((KeyStore) null);
+        TrustManager[] managers = factory.getTrustManagers();
+        return (X509TrustManager) managers[0];
+    }
+}

+ 50 - 0
src/main/java/com/nokia/finance/tasks/config/MinioConfig.java

@@ -0,0 +1,50 @@
+package com.nokia.finance.tasks.config;
+
+import io.minio.MinioClient;
+import lombok.Data;
+import okhttp3.OkHttpClient;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * minio配置
+ */
+@Data
+@Configuration
+@ConfigurationProperties("minio")
+public class MinioConfig {
+    /**
+     * 对象存储服务的URL
+     */
+    private String endpoint;
+
+    /**
+     * 存储桶
+     */
+    private String bucket;
+
+    /**
+     * 访问标识
+     */
+    private String accessKey;
+
+    /**
+     * 密钥
+     */
+    private String secretKey;
+
+    /**
+     * 链接默认过期时间,分钟
+     */
+    private Integer expiry;
+
+    @Bean
+    public MinioClient minioClient(OkHttpClient myHttpClient) {
+        return MinioClient.builder()
+                .endpoint(endpoint)
+                .credentials(accessKey, secretKey)
+                .httpClient(myHttpClient)
+                .build();
+    }
+}

+ 464 - 0
src/main/java/com/nokia/finance/tasks/dao/car/CarProcedureDao.java

@@ -1928,4 +1928,468 @@ select
             year_month = #{endYearMonth}))
 """)
     boolean hasCarBaseDataYongChe(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 插入燃油异常
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Update("""
+with
+t101 as (
+select
+    *
+from
+    car.car_base_data_month a
+where
+    first_unit != '省公司本部'
+    and position('建设部' in che_liang_suo_shu_dan_wei) = 0
+    and che_liang_lei_xing not in ('电动汽车', '特种车', '中型面包车(8-20座的面包车)', '大巴车', '货车')
+    and che_liang_shi_yong_xing_zhi not in ('特种车', '负责人用车')
+    and not exists(
+    select
+        1
+    from
+        car_theme.wz_f_spc_car b
+    where
+        a.che_pai_hao = b.card_num
+        and b.is_spec = '1')
+    and not exists(
+    select
+        1
+    from
+        car.car_bao_fei b
+    where
+        b.che_pai_hao = a.che_pai_hao
+        and b.year_month <= a.year_month)
+    and year_month = #{endYearMonth}
+),
+t102 as (
+select
+    che_pai_hao,
+        first_unit,
+        sum(ran_you) as ran_you_sum
+from
+    car.car_fei_yong_month
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    che_pai_hao,
+    first_unit
+),
+t103 as (
+select
+    che_pai_hao,
+        first_unit,
+        sum(zong_li_cheng) as zong_li_cheng_sum
+from
+    car.car_li_cheng_month
+where
+    bao_fei = 0
+    and year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    che_pai_hao,
+    first_unit
+),
+t201 as (
+select
+    t102.che_pai_hao,
+        t102.first_unit,
+        t102.ran_you_sum,
+        t103.zong_li_cheng_sum
+from
+    t102
+join t103 on
+    t102.che_pai_hao = t103.che_pai_hao
+    and t102.first_unit = t103.first_unit
+where
+    t102.ran_you_sum > 0
+    and t103.zong_li_cheng_sum > 0
+),
+t202 as (
+select
+    *,
+        ran_you_sum / zong_li_cheng_sum * 100 as bai_gong_li_you_fei,
+        ran_you_sum / zong_li_cheng_sum * 100 / 8.7 as bai_gong_li_you_hao
+from
+    t201
+),
+t203 as (
+select
+    t101.*,
+    t202.ran_you_sum,
+    t202.zong_li_cheng_sum,
+    t202.bai_gong_li_you_fei,
+    t202.bai_gong_li_you_hao
+from
+    t101
+join t202 on
+    t101.che_pai_hao = t202.che_pai_hao
+    and t101.first_unit = t202.first_unit
+),
+t204 as (
+select
+    *,
+        row_number() over (
+order by
+    bai_gong_li_you_fei desc
+        ) as bai_gong_li_you_fei_rank
+from
+    t203
+),
+t301 as (
+select
+    *
+from
+    t204
+where
+    bai_gong_li_you_fei_rank <= 50
+    and bai_gong_li_you_fei > 120
+order by
+    bai_gong_li_you_fei_rank
+)
+insert into car.car_ran_you_yi_chang
+(
+    year_month,
+    che_pai_hao,
+    first_unit,
+    second_unit,
+    third_unit,
+    che_liang_suo_shu_dan_wei,
+    che_liang_lai_yuan,
+    che_liang_lei_xing,
+    che_liang_shi_yong_xing_zhi,
+    ran_you_sum,
+    zong_li_cheng_sum,
+    bai_gong_li_you_fei,
+    bai_gong_li_you_hao,
+    bai_gong_li_you_fei_rank,
+    year_no,
+    month_no,
+    area_no,
+    area_name,
+    city_no,
+    city_name,
+    area_no2,
+    area_name2,
+    city_id,
+    city,
+    district_id,
+    district,
+    deng_ji_ri_qi,
+    che_ling
+)
+select
+    year_month,
+    che_pai_hao,
+    first_unit,
+    second_unit,
+    third_unit,
+    che_liang_suo_shu_dan_wei,
+    che_liang_lai_yuan,
+    che_liang_lei_xing,
+    che_liang_shi_yong_xing_zhi,
+    round(ran_you_sum,
+    2) as ran_you_sum,
+    round(zong_li_cheng_sum,
+    2) as zong_li_cheng_sum,
+    round(bai_gong_li_you_fei,
+    2) as bai_gong_li_you_fei,
+    round(bai_gong_li_you_hao,
+    2) as bai_gong_li_you_hao,
+    bai_gong_li_you_fei_rank,
+    year_no,
+    month_no,
+    area_no,
+    area_name,
+    city_no,
+    city_name,
+    area_no2,
+    area_name2,
+    city_id,
+    city,
+    district_id,
+    district,
+    deng_ji_ri_qi,
+    che_ling
+from
+    t301
+""")
+    int insertCarRanYouYiChang(@Param("startYearMonth") Integer startYearMonth,
+                               @Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 插入自有车辆维修费异常
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Update("""
+with
+t101 as (
+select
+    *
+from
+    car.car_base_data_month a
+where
+    che_liang_lai_yuan = '自有车辆'
+    and first_unit != '省公司本部'
+    and position('建设部' in che_liang_suo_shu_dan_wei) = 0
+    and che_liang_lei_xing not in ('电动汽车', '特种车', '中型面包车(8-20座的面包车)', '大巴车', '货车')
+    and che_liang_shi_yong_xing_zhi not in ('特种车', '负责人用车')
+    and not exists(
+    select
+        1
+    from
+        car_theme.wz_f_spc_car b
+    where
+        a.che_pai_hao = b.card_num
+        and b.is_spec = '1')
+    and not exists(
+    select
+        1
+    from
+        car.car_bao_fei b
+    where
+        b.che_pai_hao = a.che_pai_hao
+        and b.year_month <= a.year_month)
+    and year_month = #{endYearMonth}
+),
+t102 as (
+select
+    che_pai_hao,
+        first_unit,
+        sum(wei_xiu) as wei_xiu_sum
+from
+    car.car_fei_yong_month
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    che_pai_hao,
+    first_unit
+),
+t201 as (
+select
+    t101.*,
+    t102.wei_xiu_sum
+from
+    t101
+join t102 on
+    t101.che_pai_hao = t102.che_pai_hao
+    and t101.first_unit = t102.first_unit
+where
+    t102.wei_xiu_sum > 0
+),
+t202 as (
+select
+    *,
+    row_number() over (
+    order by wei_xiu_sum desc) as wei_xiu_rank
+from
+    t201
+),
+t301 as (
+select
+    *
+from
+    t202
+where
+    wei_xiu_rank <= 50
+    and wei_xiu_sum > 5000
+order by
+    wei_xiu_rank
+)
+insert
+    into
+    car.car_zi_you_wei_xiu_yi_chang
+(
+year_month,
+    che_pai_hao,
+    first_unit,
+    second_unit,
+    third_unit,
+    che_liang_suo_shu_dan_wei,
+    che_liang_lai_yuan,
+    che_liang_lei_xing,
+    che_liang_shi_yong_xing_zhi,
+    wei_xiu_sum,
+    wei_xiu_rank,
+    deng_ji_ri_qi,
+    che_ling,
+    year_no,
+    month_no,
+    area_no,
+    area_name,
+    city_no,
+    city_name,
+    area_no2,
+    area_name2,
+    city_id,
+    city,
+    district_id,
+    district
+)
+select
+    year_month,
+    che_pai_hao,
+    first_unit,
+    second_unit,
+    third_unit,
+    che_liang_suo_shu_dan_wei,
+    che_liang_lai_yuan,
+    che_liang_lei_xing,
+    che_liang_shi_yong_xing_zhi,
+    wei_xiu_sum,
+    wei_xiu_rank,
+    deng_ji_ri_qi,
+    che_ling,
+    year_no,
+    month_no,
+    area_no,
+    area_name,
+    city_no,
+    city_name,
+    area_no2,
+    area_name2,
+    city_id,
+    city,
+    district_id,
+    district
+from
+    t301
+""")
+    int insertCarZiYouWeiXiuYiChang(@Param("startYearMonth") Integer startYearMonth,
+                                    @Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 插入租赁车辆维修费异常
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Update("""
+with
+t101 as (
+select
+    *
+from
+    car.car_base_data_month a
+where
+    che_liang_lai_yuan = '租赁车辆'
+    and not exists(
+    select
+        1
+    from
+        car.car_bao_fei b
+    where
+        b.che_pai_hao = a.che_pai_hao
+        and b.year_month <= a.year_month)
+    and year_month = #{endYearMonth}
+),
+t102 as (
+select
+    che_pai_hao,
+        first_unit,
+        sum(wei_xiu) as wei_xiu_sum
+from
+    car.car_fei_yong_month
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    che_pai_hao,
+    first_unit
+),
+t201 as (
+select
+    t101.*,
+    t102.wei_xiu_sum
+from
+    t101
+join t102 on
+    t101.che_pai_hao = t102.che_pai_hao
+    and t101.first_unit = t102.first_unit
+where
+    t102.wei_xiu_sum > 0
+),
+t202 as (
+select
+    *,
+    row_number() over (
+    order by wei_xiu_sum desc) as wei_xiu_rank
+from
+    t201
+),
+t301 as (
+select
+    *
+from
+    t202
+where
+    wei_xiu_sum > 1800
+order by
+    wei_xiu_rank
+)
+insert
+    into
+    car.car_zu_lin_wei_xiu_yi_chang
+(
+year_month,
+    che_pai_hao,
+    first_unit,
+    second_unit,
+    third_unit,
+    che_liang_suo_shu_dan_wei,
+    che_liang_lai_yuan,
+    che_liang_lei_xing,
+    che_liang_shi_yong_xing_zhi,
+    wei_xiu_sum,
+    wei_xiu_rank,
+    deng_ji_ri_qi,
+    che_ling,
+    year_no,
+    month_no,
+    area_no,
+    area_name,
+    city_no,
+    city_name,
+    area_no2,
+    area_name2,
+    city_id,
+    city,
+    district_id,
+    district
+)
+select
+    year_month,
+    che_pai_hao,
+    first_unit,
+    second_unit,
+    third_unit,
+    che_liang_suo_shu_dan_wei,
+    che_liang_lai_yuan,
+    che_liang_lei_xing,
+    che_liang_shi_yong_xing_zhi,
+    wei_xiu_sum,
+    wei_xiu_rank,
+    deng_ji_ri_qi,
+    che_ling,
+    year_no,
+    month_no,
+    area_no,
+    area_name,
+    city_no,
+    city_name,
+    area_no2,
+    area_name2,
+    city_id,
+    city,
+    district_id,
+    district
+from
+    t301
+""")
+    int insertCarZuLinWeiXiuYiChang(@Param("startYearMonth") Integer startYearMonth,
+                                    @Param("endYearMonth") Integer endYearMonth);
 }

+ 1292 - 0
src/main/java/com/nokia/finance/tasks/dao/car/CarReportDao.java

@@ -0,0 +1,1292 @@
+package com.nokia.finance.tasks.dao.car;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryQsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarBszsbPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarClgkPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarCqclqkPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarDxPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarDxUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarJygxPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarJygxUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarNoticesPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarReportsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarRyycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarRyycUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarSnfyPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWgPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxQsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWzPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWzUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZlwxycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZywxycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZywxycUnitPo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarWgUnitVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+@Mapper
+public interface CarReportDao {
+    /**
+     * 查询车辆概况
+     * @param endYearMonth 账期
+     */
+    @Select("""
+select
+    count(che_liang_lai_yuan = '自有车辆' or null) as zi_you_count,
+    count(che_liang_lai_yuan = '租赁车辆' or null) as zu_lin_count,
+    count(che_liang_shi_yong_xing_zhi = '一般公务用车' or null) as gong_wu_count,
+    count(1) - count(che_liang_shi_yong_xing_zhi = '一般公务用车' or null) as sheng_chan_count,
+    count(che_liang_lei_xing = '皮卡车' or null) as pi_ka_count,
+    count(che_liang_lei_xing = '微型面包车' or null) as wei_xing_mian_bao_count,
+    count(che_liang_lei_xing = '越野车' or null) as yue_ye_count,
+    count(che_liang_lei_xing = '轿车' or null) as jiao_che_count,
+    count(1) as total
+from
+    car.car_base_data_month
+where
+    year_month = #{endYearMonth}
+""")
+    CarClgkPo clgk(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 查询产权车龄情况
+     * @param endYearMonth 账期
+     */
+    @Select("""
+with
+t101 as (
+select
+    first_unit,
+    count(che_liang_lai_yuan = '自有车辆' or null) as zi_you,
+    count((che_liang_lai_yuan = '自有车辆' and che_ling < 6) or null) as lte6,
+    count((che_liang_lai_yuan = '自有车辆' and che_ling >= 6 and che_ling <= 10) or null) as gte6lte10,
+    count((che_liang_lai_yuan = '自有车辆' and che_ling > 10) or null) as gt10,
+    count(che_liang_lai_yuan = '租赁车辆' or null) as zu_lin,
+    count(1) as total
+from
+    car.car_base_data_month
+where
+    year_month = #{endYearMonth}
+group by
+    first_unit
+order by
+    first_unit
+),
+t102 as (
+select
+    '合计' as first_unit,
+    sum(zi_you) as zi_you_total,
+    sum(lte6) as lte6,
+    sum(gte6lte10) as gte6lte10,
+    sum(gt10) as gt10,
+    sum(zu_lin) as zu_lin_total,
+    sum(total) as total
+from
+    t101
+),
+t103 as (
+select
+    *
+from
+    t101
+union all
+select
+    *
+from
+    t102
+),
+t104 as (
+select
+    *,
+    round((lte6 + zu_lin) / total::numeric,
+    4) as cheng_xin_lv
+from
+    t103
+)
+select
+    *
+from
+    t104
+""")
+    List<CarCqclqkPo> cqclqk(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 建议更新车辆一级单位统计
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Select("""
+with
+t101 as (
+select
+    *
+from
+    car.car_base_data_month
+where
+    che_liang_lai_yuan = '自有车辆'
+    and year_month = #{endYearMonth}
+),
+t102 as (
+select
+    che_pai_hao,
+    sum(wei_xiu) as wei_xiu_sum
+from
+    car.car_fei_yong_month
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    che_pai_hao
+),
+t103 as (
+select
+    t101.*,
+    t102.wei_xiu_sum
+from
+    t102
+join t101 on
+    t102.che_pai_hao = t101.che_pai_hao
+),
+t104 as (
+select
+    *
+from
+    t103
+where
+    che_ling > 10
+    and wei_xiu_sum > 5000
+),
+t105 as (
+select
+    first_unit,
+    count(che_liang_lei_xing = '轿车' or null) as jc,
+    count(che_liang_lei_xing = '皮卡车' or null) as pkc,
+    count(che_liang_lei_xing = '商务车' or null) as swc,
+    count(che_liang_lei_xing = '特种车' or null) as tzc,
+    count(che_liang_lei_xing = '越野车' or null) as yyc,
+    count(che_liang_lei_xing = '中型面包车(8-20座的面包车)' or null) as zxmbc,
+    count(1) as total
+from
+    t104
+group by
+    first_unit
+order by
+    count(1) desc
+),
+t106 as (
+select
+    '总计' as first_unit,
+    coalesce(sum(jc), 0) as jc,
+    coalesce(sum(pkc), 0) as pkc,
+    coalesce(sum(swc), 0) as swc,
+    coalesce(sum(tzc), 0) as tzc,
+    coalesce(sum(yyc), 0) as yyc,
+    coalesce(sum(zxmbc), 0) as zxmbc,
+    coalesce(sum(total), 0) as total
+from
+    t105
+),
+t107 as (
+select
+    *
+from
+    t105
+union all
+select
+    *
+from
+    t106
+)
+select
+    *
+from
+    t107
+""")
+    List<CarJygxUnitPo> jygxUnit(@Param("startYearMonth") Integer startYearMonth,
+                                 @Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 建议更新车辆
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Select("""
+with
+t101 as (
+select
+    *
+from
+    car.car_base_data_month
+where
+    che_liang_lai_yuan = '自有车辆'
+    and year_month = #{endYearMonth}
+),
+t102 as (
+select
+    che_pai_hao,
+    sum(wei_xiu) as wei_xiu_sum
+from
+    car.car_fei_yong_month
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    che_pai_hao
+),
+t103 as (
+select
+    t101.*,
+    t102.wei_xiu_sum
+from
+    t102
+join t101 on
+    t102.che_pai_hao = t101.che_pai_hao
+),
+t104 as (
+select
+    *
+from
+    t103
+where
+    che_ling > 10
+    and wei_xiu_sum > 5000
+)
+select
+    che_pai_hao,
+    che_liang_pin_pai,
+    deng_ji_ri_qi,
+    che_liang_lai_yuan,
+    che_liang_lei_xing,
+    che_liang_shi_yong_xing_zhi,
+    che_liang_suo_shu_dan_wei,
+    first_unit,
+    second_unit,
+    third_unit,
+    ceil(che_ling) as che_ling,
+    round(wei_xiu_sum,
+    2) as wei_xiu_sum
+from
+    t104
+order by
+    wei_xiu_sum desc
+""")
+    List<CarJygxPo> jygx(@Param("startYearMonth") Integer startYearMonth,
+                         @Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 查询省内费用
+     * @param endYearMonth 账期
+     */
+    @Select("""
+with
+t101 as (
+select
+    year_no,
+    month_no,
+    second_org_no,
+    case
+        when second_org_name = '省机动局' then '传输局'
+        else second_org_name
+    end,
+    round(sum(case when kpi_id in ('KPI_001', 'KPI_002', 'KPI_004', 'KPI_005', 'KPI_006', 'KPI_007', 'KPI_008', 'KPI_009', 'KPI_010', 'KPI_011', 'KPI_013', 'KPI_014', 'KPI_015', 'KPI_016', 'KPI_017', 'KPI_018', 'KPI_019', 'KPI_020', 'KPI_021', 'KPI_022', 'KPI_023') then ty_value else 0 end) / 10000,
+    2) as ty_fy,
+    round(sum(case when kpi_id in ('KPI_001', 'KPI_002', 'KPI_004', 'KPI_005', 'KPI_006', 'KPI_007', 'KPI_008', 'KPI_009', 'KPI_010', 'KPI_011', 'KPI_013', 'KPI_014', 'KPI_015', 'KPI_016', 'KPI_017', 'KPI_018', 'KPI_019', 'KPI_020', 'KPI_021', 'KPI_022', 'KPI_023') then ly_value else 0 end) / 10000,
+    2) as ly_fy,
+    round(sum(case when kpi_id = 'KPI_024' then ty_value else 0 end) / 10000,
+    2) as ty_sr
+from
+    car.car_fee_hb
+where
+    month_id = #{endYearMonth}
+    and second_org_no in ('-11', '-12', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '720', '782')
+group by
+    year_no,
+    month_no,
+    second_org_no,
+    second_org_name
+),
+t102 as (
+select
+    t101.*,
+    b.budget
+from
+    t101
+join car.car_yu_suan b on
+    t101.second_org_no = b.area_no
+    and t101.year_no = b.year_no
+),
+t103 as (
+select
+    *,
+    round(budget / 12 * month_no,
+    2) as budget_lj,
+    ty_fy - ly_fy as tbzj,
+    case
+        when ly_fy = 0 then null
+        else round((ty_fy - ly_fy) / ly_fy,
+        4)
+    end as tbbfb,
+    ty_fy - round(budget / 12 * month_no,
+    2) as yspc,
+    case
+        when budget = 0 then null
+        else round((ty_fy - round(budget / 12 * month_no,
+        2)) / (round(budget / 12 * month_no,
+        2)),
+        5)
+    end as yspcbfb,
+    case
+        when ty_sr = 0 then null
+        else round(ty_fy / ty_sr,
+        5)
+    end as ty_zsb
+from
+    t102
+),
+t104 as (
+select
+    max(year_no) as year_no,
+    max(month_no) as month_no,
+    '018' as second_org_no,
+    '合计' as second_org_name,
+    sum(ty_fy) as ty_fy,
+    sum(ly_fy) as ly_fy,
+    sum(ty_sr) as ty_sr,
+    sum(budget) as budget,
+    sum(budget_lj) as budget_lj,
+    sum(ty_fy) - sum(ly_fy) as tbzj,
+    case
+        when sum(ly_fy) = 0 then null
+        else round((sum(ty_fy) - sum(ly_fy)) / sum(ly_fy),
+        4)
+    end as tbbfb,
+    sum(ty_fy) - sum(budget_lj) as yspc,
+    case
+        when sum(budget_lj) = 0 then null
+        else round((sum(ty_fy) - sum(budget_lj)) / (sum(budget_lj)),
+        4)
+    end as yspcbfb,
+    case
+        when sum(ty_sr) = 0 then null
+        else round(sum(ty_fy) / sum(ty_sr),
+        5)
+    end as ty_zsb
+from
+    t103
+),
+t105 as (
+select
+    *
+from
+    t103
+union all
+select
+    *
+from
+    t104
+)
+select
+    *
+from
+    t105
+""")
+    List<CarSnfyPo> snfy(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 查询北十占收比
+     * @param endYearMonth 账期
+     */
+    @Select("""
+with
+t101 as (
+select
+    area_name,
+    round(sum(case when kpi_id in ('KPI_001', 'KPI_002', 'KPI_004', 'KPI_005', 'KPI_006', 'KPI_007', 'KPI_008', 'KPI_009', 'KPI_010', 'KPI_011', 'KPI_013', 'KPI_014', 'KPI_015', 'KPI_016', 'KPI_017', 'KPI_018', 'KPI_019', 'KPI_020', 'KPI_021', 'KPI_022', 'KPI_023') then ty_value else 0 end) / 10000,
+    2) as ty_fy,
+    round(sum(case when kpi_id = 'KPI_024' then ty_value else 0 end) / 10000,
+    2) as ty_sr
+from
+    car.car_fee_bs
+where
+    month_id = #{endYearMonth}
+group by
+    area_name
+),
+t102 as (
+select
+    *,
+    case
+        when ty_sr = 0 then null
+        else round(ty_fy / ty_sr,
+        5)
+    end as ty_zsb
+from
+    t101
+),
+t103 as (
+select
+    *,
+    row_number() over (
+    order by ty_zsb desc) as ty_zsb_rank
+from
+    t102
+)
+select
+    *
+from
+    t103
+order by
+    ty_zsb
+""")
+    List<CarBszsbPo> bszsb(@Param("endYearMonth") Integer endYearMonth);
+
+
+    /**
+     * 1-12月百公里燃油费变化情况
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Select("""
+with
+t101 as (
+select
+    month_no,
+    sum(case when kpi_id in ('KPI_004', 'KPI_013') then tm_value else 0 end) as tm_ry
+from
+    car.car_fee_hb
+where
+    month_id >= #{startYearMonth}
+    and month_id <= #{endYearMonth}
+group by
+    month_no
+),
+t102 as (
+select
+    month_no,
+    sum(zong_li_cheng) as tm_lc
+from
+    car.car_li_cheng_month
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    month_no
+),
+t103 as (
+select
+    t101.month_no,
+    t101.tm_ry,
+    t102.tm_lc
+from
+    t101
+join t102 on
+    t101.month_no = t102.month_no
+),
+t104 as (
+select
+    *,
+    round(tm_ry / tm_lc * 100,
+    2) as bglry
+from
+    t103
+)
+select
+    *
+from
+    t104
+order by
+    month_no
+""")
+    List<CarBglryQsPo> bglryQs(@Param("startYearMonth") Integer startYearMonth,
+                               @Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 二级组织机构百公里燃油费
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Select("""
+with
+t100 as (
+select
+    id as area_no,
+    case
+        when name = '省机动局' then '机动局'
+        else name
+    end as area_name
+from
+    common.organization
+where
+    id in ('-11', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '720', '782')
+),
+t101 as (
+select
+    second_org_no as area_no,
+    sum(case when kpi_id in ('KPI_004', 'KPI_013') then ty_value else 0 end) as ty_ry
+from
+    car.car_fee_hb
+where
+    month_id = #{endYearMonth}
+group by
+    second_org_no
+),
+t102 as (
+select
+    area_no,
+    sum(zong_li_cheng) as ty_lc
+from
+    car.car_li_cheng_month
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    area_no
+),
+t103 as (
+select
+    t100.area_no,
+    t100.area_name,
+    t101.ty_ry,
+    t102.ty_lc
+from
+    t100
+left join t101 on
+    t100.area_no = t101.area_no
+left join t102 on
+    t100.area_no = t102.area_no
+),
+t104 as (
+select
+    *,
+    case
+        when ty_lc = 0 then 0
+        else coalesce(round(ty_ry / ty_lc * 100,
+        2),
+        0)
+    end as bglry
+from
+    t103
+),
+t105 as (
+select
+    '平均' as area_no,
+    '平均' as area_name,
+    coalesce(sum(ty_ry),
+    0) as ty_ry,
+    coalesce(sum(ty_lc),
+    0) as ty_lc,
+    coalesce(round(avg(bglry),
+    2),
+    0) as bglry
+from
+    t104
+),
+t106 as (
+select
+    *
+from
+    t104
+union all
+select
+    *
+from
+    t105
+)
+select
+    *
+from
+    t106
+order by
+    bglry
+""")
+    List<CarBglryUnitPo> bglryUnit(@Param("startYearMonth") Integer startYearMonth,
+                                   @Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 1-12月维修费变化情况
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     */
+    @Select("""
+select
+    month_no,
+    round(sum(case when kpi_id in ('KPI_008', 'KPI_016') then tm_value else 0 end) / 10000,
+    2) as tm_wx
+from
+    car.car_fee_hb
+where
+    month_id >= #{startYearMonth}
+    and month_id <= #{endYearMonth}
+group by
+    month_no
+order by
+    month_no
+""")
+    List<CarWxQsPo> wxQs(@Param("startYearMonth") Integer startYearMonth,
+                         @Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 二级组织机构自有车辆单车维修费
+     * @param endYearMonth 账期
+     */
+    @Select("""
+with
+t100 as (
+select
+    id as area_no,
+    case
+        when name = '省机动局' then '机动局'
+        else name
+    end as area_name
+from
+    common.organization
+where
+    id in ('-11', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '720', '782')
+),
+t101 as (
+select
+    second_org_no as area_no,
+    sum(case when kpi_id in ('KPI_008', 'KPI_016') then ty_value else 0 end) as ty_wx
+from
+    car.car_fee_hb
+where
+    month_id = #{endYearMonth}
+group by
+    second_org_no
+),
+t102 as (
+select
+    area_no,
+    count(1) as total
+from
+    car.car_base_data_month
+where
+    year_month = #{endYearMonth}
+group by
+    area_no
+),
+t103 as (
+select
+    t100.area_no,
+    t100.area_name,
+    t101.ty_wx,
+    t102.total
+from
+    t100
+left join t101 on
+    t100.area_no = t101.area_no
+left join t102 on
+    t100.area_no = t102.area_no
+),
+t104 as (
+select
+    *,
+    case
+        when total = 0 then 0
+        else coalesce(round(ty_wx / total),
+        0)
+    end as ty_wx_avg
+from
+    t103
+),
+t105 as (
+select
+    '平均' as area_no,
+    '平均' as area_name,
+    coalesce(sum(ty_wx),
+    0) as ty_wx,
+    coalesce(sum(total),
+    0) as total,
+    coalesce(round(avg(ty_wx_avg)),
+    0) as ty_wx_avg
+from
+    t104
+),
+t106 as (
+select
+    *
+from
+    t104
+union all
+select
+    *
+from
+    t105
+)
+select
+    *
+from
+    t106
+order by
+    ty_wx_avg
+""")
+    List<CarWxUnitPo> wxUnit(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 查询异常燃油费
+     * @param endYearMonth 账期
+     */
+    @Select("""
+select
+    *
+from
+    car.car_ran_you_yi_chang
+where
+    year_month = #{endYearMonth}
+order by
+    bai_gong_li_you_fei_rank
+""")
+    List<CarRyycPo> ryyc(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 查询异常燃油费一级单位统计
+     * @param endYearMonth 账期
+     */
+    @Select("""
+with
+t101 as (
+select
+    first_unit,
+    count(1) as total
+from
+    car.car_ran_you_yi_chang
+where
+    year_month = #{endYearMonth}
+group by
+    first_unit
+order by
+    count(1) desc
+),
+t102 as (
+select
+    '总计' as first_unit,
+    coalesce(sum(total),
+    0) as total
+from
+    t101
+),
+t103 as (
+select
+    *
+from
+    t101
+union all
+select
+    *
+from
+    t102
+)
+select
+    *
+from
+    t103
+""")
+    List<CarRyycUnitPo> ryycUnit(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 自有车辆维修费异常
+     * @param endYearMonth 账期
+     */
+    @Select("""
+select
+    *
+from
+    car.car_zi_you_wei_xiu_yi_chang
+where
+    year_month = #{endYearMonth}
+order by
+    wei_xiu_rank
+""")
+    List<CarZywxycPo> zywxyc(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 查询自有车辆维修费异常一级单位统计
+     * @param endYearMonth 账期
+     */
+    @Select("""
+with
+t101 as (
+select
+    first_unit,
+    count(1) as total
+from
+    car.car_zi_you_wei_xiu_yi_chang
+where
+    year_month = #{endYearMonth}
+group by
+    first_unit
+order by
+    count(1) desc
+),
+t102 as (
+select
+    '总计' as first_unit,
+    coalesce(sum(total),
+    0) as total
+from
+    t101
+),
+t103 as (
+select
+    *
+from
+    t101
+union all
+select
+    *
+from
+    t102
+)
+select
+    *
+from
+    t103
+""")
+    List<CarZywxycUnitPo> zywxycUnit(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 租赁车辆维修费异常
+     * @param endYearMonth 账期
+     */
+    @Select("""
+select
+    *
+from
+    car.car_zu_lin_wei_xiu_yi_chang
+where
+    year_month = #{endYearMonth}
+order by
+    wei_xiu_rank
+""")
+    List<CarZlwxycPo> zlwxyc(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 低效车辆一级单位统计
+     * @param ty 今年账期
+     * @param ly 去年同期
+     */
+    @Select("""
+with
+t101 as (
+select
+    first_unit,
+    count(1) as total
+from
+    car.car_base_data_month
+where
+    year_month = #{ly}
+    and first_unit != '省公司本部'
+    and position('建设部' in che_liang_suo_shu_dan_wei) = 0
+group by
+    first_unit
+),
+t102 as (
+select
+    first_unit,
+    count(1) as di_xiao_count
+from
+    car.car_di_xiao_month
+where
+    year_month = #{ly}
+group by
+    first_unit
+),
+t103 as (
+select
+    t101.first_unit,
+    t101.total,
+    case
+        when t102.di_xiao_count is null then 0
+        else t102.di_xiao_count
+    end,
+    case
+        when t102.di_xiao_count is null then 0
+        else t102.di_xiao_count / t101.total::numeric
+    end as di_xiao_percent
+from
+    t101
+left join t102 on
+    t101.first_unit = t102.first_unit
+),
+t201 as (
+select
+    first_unit,
+    count(1) as total
+from
+    car.car_base_data_month
+where
+    year_month = #{ty}
+    and first_unit != '省公司本部'
+    and position('建设部' in che_liang_suo_shu_dan_wei) = 0
+group by
+    first_unit
+),
+t202 as (
+select
+    first_unit,
+    count(1) as di_xiao_count
+from
+    car.car_di_xiao_month
+where
+    year_month = #{ty}
+group by
+    first_unit
+),
+t203 as (
+select
+    t201.first_unit,
+    t201.total,
+    case
+        when t202.di_xiao_count is null then 0
+        else t202.di_xiao_count
+    end,
+    case
+        when t202.di_xiao_count is null then 0
+        else t202.di_xiao_count / t201.total::numeric
+    end as di_xiao_percent
+from
+    t201
+left join t202 on
+    t201.first_unit = t202.first_unit
+),
+t301 as (
+select
+    t203.first_unit,
+    t103.total as total_ly,
+    t103.di_xiao_count as di_xiao_count_ly,
+    t103.di_xiao_percent as di_xiao_percent_ly,
+    t203.total as total_ty,
+    t203.di_xiao_count as di_xiao_count_ty,
+    t203.di_xiao_percent as di_xiao_percent_ty,
+    t203.di_xiao_percent - t103.di_xiao_percent as di_xiao_change
+from
+    t103
+join t203 on
+    t103.first_unit = t203.first_unit
+),
+t302 as (
+select
+    '合计' as first_unit,
+    sum(total_ly) as total_ly,
+    sum(di_xiao_count_ly) as di_xiao_count_ly,
+    sum(di_xiao_count_ly) / sum(total_ly)::numeric as di_xiao_percent_ly,
+    sum(total_ty) as total_ty,
+    sum(di_xiao_count_ty) as di_xiao_count_ty,
+    sum(di_xiao_count_ty) / sum(total_ty)::numeric as di_xiao_percent_ty,
+    sum(di_xiao_count_ty) / sum(total_ty)::numeric - sum(di_xiao_count_ly) / sum(total_ly)::numeric as di_xiao_change
+from
+    t301
+),
+t401 as (
+select
+    *
+from
+    t301
+union all
+select
+    *
+from
+    t302
+)
+select
+    first_unit,
+    coalesce(total_ly, 0) as total_ly,
+    coalesce(di_xiao_count_ly, 0) as di_xiao_count_ly,
+    coalesce(round(di_xiao_percent_ly, 4), 0) as di_xiao_percent_ly,
+    coalesce(total_ty, 0) as total_ty,
+    coalesce(di_xiao_count_ty, 0) as di_xiao_count_ty,
+    coalesce(round(di_xiao_percent_ty, 4), 0) as di_xiao_percent_ty,
+    coalesce(round(di_xiao_change, 4), 0) as di_xiao_change
+from
+    t401
+""")
+    List<CarDxUnitPo> dxUnit(@Param("ty") Integer ty, @Param("ly") Integer ly);
+
+    /**
+     * 低效车辆明细
+     * @param endYearMonth 账期
+     */
+    @Select("""
+select
+    *
+from
+    car.car_di_xiao_month
+where
+    year_month = #{endYearMonth}
+order by
+    first_unit,
+    second_unit,
+    third_unit,
+    che_pai_hao
+""")
+    List<CarDxPo> dx(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 违规用车一级单位统计
+     * @param startYearMonth 开始年月
+     * @param endYearMonth 结束年月
+     * @param endMonth 结束月
+     */
+    @Select("""
+with
+t100
+as (
+select
+    '石家庄' as first_unit
+union all
+select
+    '唐山'
+union all
+select
+    '秦皇岛'
+union all
+select
+    '邯郸'
+union all
+select
+    '邢台'
+union all
+select
+    '保定'
+union all
+select
+    '张家口'
+union all
+select
+    '承德'
+union all
+select
+    '廊坊'
+union all
+select
+    '沧州'
+union all
+select
+    '衡水'
+union all
+select
+    '雄安'
+union all
+select
+    '机动局'
+),
+t101 as (
+select
+    first_unit,
+    count(month_no = 1 or null) as m1,
+    count(month_no = 2 or null) as m2,
+    count(month_no = 3 or null) as m3,
+    count(month_no = 4 or null) as m4,
+    count(month_no = 5 or null) as m5,
+    count(month_no = 6 or null) as m6,
+    count(month_no = 7 or null) as m7,
+    count(month_no = 8 or null) as m8,
+    count(month_no = 9 or null) as m9,
+    count(month_no = 10 or null) as m10,
+    count(month_no = 11 or null) as m11,
+    count(month_no = 12 or null) as m12,
+    count(1) as total
+from
+    car.car_wei_gui
+where
+    year_month >= #{startYearMonth}
+    and year_month <= #{endYearMonth}
+group by
+    first_unit
+),
+t102 as (
+select
+    t100.first_unit,
+    t101.m1,
+    t101.m2,
+    t101.m3,
+    t101.m4,
+    t101.m5,
+    t101.m6,
+    t101.m7,
+    t101.m8,
+    t101.m9,
+    t101.m10,
+    t101.m11,
+    t101.m12,
+    t101.total
+from
+    t100
+left join t101 on
+    t100.first_unit = t101.first_unit
+),
+t103 as (
+select
+    '合计' as first_unit,
+    sum(m1) as m1,
+    sum(m2) as m2,
+    sum(m3) as m3,
+    sum(m4) as m4,
+    sum(m5) as m5,
+    sum(m6) as m6,
+    sum(m7) as m7,
+    sum(m8) as m8,
+    sum(m9) as m9,
+    sum(m10) as m10,
+    sum(m11) as m11,
+    sum(m12) as m12,
+    sum(total) as total
+from
+    t102
+),
+t104 as (
+select * from t102
+union all
+select * from t103
+)
+select
+first_unit,
+case when 1 <= #{endMonth} then coalesce(m1, 0)::varchar else '' end as m1,
+case when 2 <= #{endMonth} then coalesce(m2, 0)::varchar else '' end as m2,
+case when 3 <= #{endMonth} then coalesce(m3, 0)::varchar else '' end as m3,
+case when 4 <= #{endMonth} then coalesce(m4, 0)::varchar else '' end as m4,
+case when 5 <= #{endMonth} then coalesce(m5, 0)::varchar else '' end as m5,
+case when 6 <= #{endMonth} then coalesce(m6, 0)::varchar else '' end as m6,
+case when 7 <= #{endMonth} then coalesce(m7, 0)::varchar else '' end as m7,
+case when 8 <= #{endMonth} then coalesce(m8, 0)::varchar else '' end as m8,
+case when 9 <= #{endMonth} then coalesce(m9, 0)::varchar else '' end as m9,
+case when 10 <= #{endMonth} then coalesce(m10, 0)::varchar else '' end as m10,
+case when 11 <= #{endMonth} then coalesce(m11, 0)::varchar else '' end as m11,
+case when 12 <= #{endMonth} then coalesce(m12, 0)::varchar else '' end as m12,
+coalesce(total, 0)::varchar as total
+from t104
+""")
+    List<CarWgUnitVo> wgUnit(@Param("startYearMonth") Integer startYearMonth,
+                             @Param("endYearMonth") Integer endYearMonth, @Param("endMonth") Integer endMonth);
+
+    /**
+     * 违规用车明细
+     * @param endYearMonth 账期
+     */
+    @Select("""
+select
+    *
+from
+    car.car_wei_gui
+where
+    year_month = #{endYearMonth}
+order by
+    yue_jie_shi_jian
+""")
+    List<CarWgPo> wg(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 违章长期未处理一级单位统计
+     * @param endYearMonth 账期
+     */
+    @Select("""
+with
+t101 as (
+select
+    first_unit,
+    count(1) as total
+from
+    car.car_wei_zhang_chang_qi
+where
+    year_month = #{endYearMonth}
+group by
+    first_unit
+order by
+    count(1) desc
+),
+t102 as (
+select
+    '总计' as first_unit,
+    coalesce(sum(total),
+    0) as total
+from
+    t101
+),
+t103 as (
+select
+    *
+from
+    t101
+union all
+select
+    *
+from
+    t102
+)
+select
+    *
+from
+    t103
+""")
+    List<CarWzUnitPo> wzUnit(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 违章长期未处理明细
+     * @param endYearMonth 账期
+     */
+    @Select("""
+select
+    *
+from
+    car.car_wei_zhang_chang_qi
+where
+    year_month = #{endYearMonth}
+order by
+    wei_zhang_shi_jian
+""")
+    List<CarWzPo> wz(@Param("endYearMonth") Integer endYearMonth);
+
+    /**
+     * 批量插入报告url
+     */
+    @Update("""
+<script>
+insert into car.car_reports
+(
+year_month,
+file_type,
+url
+)
+values
+<foreach collection="list" item="item" index="index" separator=",">
+(
+#{item.yearMonth},
+#{item.fileType},
+#{item.url}
+)
+</foreach>
+</script>
+""")
+    int insertBatchCarReports(List<CarReportsPo> list);
+
+    /**
+     * 批量插入公告
+     */
+    @Update("""
+<script>
+insert into car.notices
+(
+year_month,
+city,
+content,
+create_time
+)
+values
+<foreach collection="list" item="item" index="index" separator=",">
+(
+#{item.yearMonth},
+#{item.city},
+#{item.content},
+#{item.createTime}
+)
+</foreach>
+</script>
+""")
+    int insertBatchCarNotices(List<CarNoticesPo> list);
+}

+ 4 - 0
src/main/java/com/nokia/finance/tasks/enums/JobEnum.java

@@ -77,5 +77,9 @@ public enum JobEnum {
      * 睿行车辆行驶里程日数据入库定时任务
      */
     CAR_LI_CHENG_DAY_JOB,
+    /**
+     * 车辆报告定时任务
+     */
+    CAR_REPORT_JOB,
     ;
 }

+ 310 - 0
src/main/java/com/nokia/finance/tasks/jobs/car/CarReportJob.java

@@ -0,0 +1,310 @@
+package com.nokia.finance.tasks.jobs.car;
+
+import com.nokia.finance.tasks.common.exception.MyRuntimeException;
+import com.nokia.finance.tasks.config.CarReportConfig;
+import com.nokia.finance.tasks.dao.car.CarReportDao;
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryQsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarBszsbPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarClgkPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarCqclqkPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarDxPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarDxUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarJygxPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarJygxUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarNoticesPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarReportsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarRyycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarRyycUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarSnfyPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWgPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxQsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWzPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWzUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZlwxycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZywxycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZywxycUnitPo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarCldxVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarClfyVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarClgkVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarDxUnitVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarReportVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarWgUnitVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarWgycVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarWzUnitVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarWzclycVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarYcryfVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarZlycwxVo;
+import com.nokia.finance.tasks.pojo.vo.car_report.CarZyycwxVo;
+import com.nokia.finance.tasks.service.common.file.FileService;
+import com.nokia.finance.tasks.utils.OfficeUtil;
+import com.nokia.finance.tasks.utils.ZipUtil;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.text.StringSubstitutor;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 车辆报告定时任务
+ */
+@Slf4j
+@Service
+public class CarReportJob {
+    private final CarReportConfig carReportConfig;
+    private final CarReportDao carReportDao;
+    private final FileService fileService;
+
+    public CarReportJob(CarReportConfig carReportConfig, CarReportDao carReportDao, FileService fileService) {
+        this.carReportConfig = carReportConfig;
+        this.carReportDao = carReportDao;
+        this.fileService = fileService;
+    }
+
+    /**
+     * 执行任务
+     */
+    @Scheduled(cron = "0 30 0 13 * ?")
+    @Transactional(timeout = 300, rollbackFor = Exception.class)
+    public void runJob() {
+        try {
+            log.info("执行车辆报告定时任务");
+            CarReportVo vo = getCarReportVo();
+            // 生成docx
+            generateDocx(vo);
+            // 生成pdf
+            OfficeUtil.toPdf(carReportConfig.getOutDir(), carReportConfig.getDocx(), 1L);
+            // 上传文件
+            upload(vo);
+            // 更新公告
+            updateNotices(vo);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new MyRuntimeException("车辆报告定时任务失败");
+        }
+    }
+
+    public CarReportVo getCarReportVo() throws IOException {
+        LocalDate localDateNow = LocalDate.now();
+        LocalDate localDateEnd = localDateNow.minusMonths(1);
+        LocalDate localDateStart = localDateEnd.withDayOfYear(1);
+        LocalDate localDateLastYear = localDateEnd.minusYears(1);
+        Integer endYearMonth = Integer.valueOf(localDateEnd.format(DateTimeFormatter.ofPattern("yyyyMM")));
+        Integer startYearMonth = Integer.valueOf(localDateStart.format(DateTimeFormatter.ofPattern("yyyyMM")));
+        Integer yearMonthLastYear = Integer.valueOf(localDateLastYear.format(DateTimeFormatter.ofPattern("yyyyMM")));
+        Integer endMonth = localDateEnd.getMonthValue();
+        CarReportVo vo = new CarReportVo();
+        vo.setReportYear(String.valueOf(localDateEnd.getYear()));
+        vo.setReportMonth(String.valueOf(endMonth));
+        vo.setCurrentYear(String.valueOf(localDateNow.getYear()));
+        vo.setCurrentMonth(String.valueOf(localDateNow.getMonthValue()));
+        vo.setLastReportYear(String.valueOf(localDateLastYear.getYear()));
+        vo.setEndYearMonth(endYearMonth);
+        // 车辆概况
+        CarClgkPo carClgkPo = carReportDao.clgk(endYearMonth);
+        // 产权车龄情况
+        List<CarCqclqkPo> carCqclqkPoList = carReportDao.cqclqk(endYearMonth);
+        // 建议更新车辆一级单位统计
+        List<CarJygxUnitPo> carJygxUnitPoList = carReportDao.jygxUnit(startYearMonth, endYearMonth);
+        // 建议更新车辆明细
+        List<CarJygxPo> carJygxPoList = carReportDao.jygx(startYearMonth, endYearMonth);
+        vo.setClgk(new CarClgkVo(carClgkPo, carCqclqkPoList, carJygxUnitPoList, carJygxPoList, carReportConfig));
+        // 省内费用
+        List<CarSnfyPo> carSnfyPoList = carReportDao.snfy(endYearMonth);
+        // 北十占收比
+        List<CarBszsbPo> carBszsbPoList = carReportDao.bszsb(endYearMonth);
+        // 1-12月百公里燃油费变化情况
+        List<CarBglryQsPo> carBglryQsPoList = carReportDao.bglryQs(startYearMonth, endYearMonth);
+        // 二级组织机构百公里燃油费
+        List<CarBglryUnitPo> carBglryUnitPoList = carReportDao.bglryUnit(startYearMonth, endYearMonth);
+        // 1-12月维修费变化情况
+        List<CarWxQsPo> carWxQsPoList = carReportDao.wxQs(startYearMonth, endYearMonth);
+        // 二级组织机构自有车辆单车维修费
+        List<CarWxUnitPo> carWxUnitPoList = carReportDao.wxUnit(endYearMonth);
+        vo.setClfy(new CarClfyVo(carSnfyPoList, carBszsbPoList, carBglryQsPoList, carBglryUnitPoList, carWxQsPoList,
+                carWxUnitPoList));
+        // 异常燃油费一级单位统计
+        List<CarRyycUnitPo> carRyycUnitPoList = carReportDao.ryycUnit(endYearMonth);
+        // 异常燃油费明细
+        List<CarRyycPo> carRyycPoList = carReportDao.ryyc(endYearMonth);
+        vo.setYcryf(new CarYcryfVo(carRyycUnitPoList, carRyycPoList, carReportConfig));
+        // 自有车辆维修费异常一级单位统计
+        List<CarZywxycUnitPo> carZywxycUnitPoList = carReportDao.zywxycUnit(endYearMonth);
+        // 自有车辆维修费异常
+        List<CarZywxycPo> carZywxycPoList = carReportDao.zywxyc(endYearMonth);
+        vo.setZyycwx(new CarZyycwxVo(carZywxycUnitPoList, carZywxycPoList, carReportConfig));
+        // 租赁车辆维修费异常
+        List<CarZlwxycPo> carZlwxycPoList = carReportDao.zlwxyc(endYearMonth);
+        vo.setZlycwx(new CarZlycwxVo(carZlwxycPoList));
+        // 低效车辆一级单位统计
+        List<CarDxUnitPo> carDxUnitPoList = carReportDao.dxUnit(endYearMonth, yearMonthLastYear);
+        // 低效车辆明细
+        List<CarDxPo> carDxPoList = carReportDao.dx(endYearMonth);
+        vo.setCldx(new CarCldxVo(carDxUnitPoList, carDxPoList, carReportConfig));
+        // 违规用车一级单位统计
+        List<CarWgUnitVo> carWgUnitVoList = carReportDao.wgUnit(startYearMonth, endYearMonth, endMonth);
+        // 违规用车明细
+        List<CarWgPo> carWgPoList = carReportDao.wg(endYearMonth);
+        vo.setWgyc(new CarWgycVo(carWgUnitVoList, carWgPoList, carReportConfig));
+        // 违章长期未处理一级单位统计
+        List<CarWzUnitPo> carWzUnitPoList = carReportDao.wzUnit(endYearMonth);
+        // 违章长期未处理明细
+        List<CarWzPo> carWzPoList = carReportDao.wz(endYearMonth);
+        vo.setWzclyc(new CarWzclycVo(carWzUnitPoList, carWzPoList, carReportConfig));
+        return vo;
+    }
+
+    /**
+     * 生成docx
+     */
+    public void generateDocx(CarReportVo vo) throws IOException, TemplateException {
+        Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
+        configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
+        configuration.setDirectoryForTemplateLoading(new File(carReportConfig.getFtlDir()));
+        // 生成document.xml
+        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(carReportConfig.getDocumentXml()),
+                StandardCharsets.UTF_8)) {
+            Template template = configuration.getTemplate(carReportConfig.getDocumentFtl(),
+                    StandardCharsets.UTF_8.name());
+            template.process(vo, writer);
+        }
+        // 生成北十占收比图表xml
+        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(carReportConfig.getBszsbChartXml()),
+                StandardCharsets.UTF_8)) {
+            Template template = configuration.getTemplate(carReportConfig.getBszsbChartFtl(),
+                    StandardCharsets.UTF_8.name());
+            template.process(vo, writer);
+        }
+        // 生成1-12月百公里燃油费变化情况图表xml
+        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(carReportConfig.getBglryQsChartXml()),
+                StandardCharsets.UTF_8)) {
+            Template template = configuration.getTemplate(carReportConfig.getBglryQsChartFtl(),
+                    StandardCharsets.UTF_8.name());
+            template.process(vo, writer);
+        }
+        // 生成二级组织机构百公里燃油图表xml
+        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(carReportConfig.getBglryUnitChartXml()),
+                StandardCharsets.UTF_8)) {
+            Template template = configuration.getTemplate(carReportConfig.getBglryUnitChartFtl(),
+                    StandardCharsets.UTF_8.name());
+            template.process(vo, writer);
+        }
+        // 生成1-12月维修费变化情况图表xml
+        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(carReportConfig.getWxQsChartXml()),
+                StandardCharsets.UTF_8)) {
+            Template template = configuration.getTemplate(carReportConfig.getWxQsChartFtl(),
+                    StandardCharsets.UTF_8.name());
+            template.process(vo, writer);
+        }
+        // 生成二级组织机构自有车辆单车维修费图表xml
+        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(carReportConfig.getWxUnitChartXml()),
+                StandardCharsets.UTF_8)) {
+            Template template = configuration.getTemplate(carReportConfig.getWxUnitChartFtl(),
+                    StandardCharsets.UTF_8.name());
+            template.process(vo, writer);
+        }
+        Files.createDirectories(Paths.get(carReportConfig.getOutDir()));
+        Path inputDir = Paths.get(carReportConfig.getDocxDir());
+        Path outputFile = Paths.get(carReportConfig.getDocx());
+        ZipUtil.zipDirNonSelf(inputDir, outputFile);
+    }
+
+    /**
+     * 上传文件
+     */
+    public void upload(CarReportVo vo) throws IOException {
+        Integer endYearMonth = vo.getEndYearMonth();
+        List<CarReportsPo> list = new ArrayList<>();
+        byte[] bytes = Files.readAllBytes(Paths.get(carReportConfig.getDocx()));
+        long objectSize = bytes.length;
+        String object = "oss/reports/car/" + endYearMonth + ".docx";
+        fileService.putObject(object, new ByteArrayInputStream(bytes), objectSize, null);
+        CarReportsPo po1 = new CarReportsPo();
+        po1.setYearMonth(endYearMonth);
+        po1.setFileType("word");
+        po1.setUrl(object);
+        list.add(po1);
+        bytes = Files.readAllBytes(Paths.get(carReportConfig.getPdf()));
+        objectSize = bytes.length;
+        object = "oss/reports/car/" + endYearMonth + ".pdf";
+        fileService.putObject(object, new ByteArrayInputStream(bytes), objectSize, null);
+        CarReportsPo po2 = new CarReportsPo();
+        po2.setYearMonth(endYearMonth);
+        po2.setFileType("pdf");
+        po2.setUrl(object);
+        list.add(po2);
+        int updateCount = carReportDao.insertBatchCarReports(list);
+        if (updateCount == 0) {
+            throw new MyRuntimeException("插入car.car_reports失败");
+        }
+    }
+
+    /**
+     * 更新公告
+     */
+    public void updateNotices(CarReportVo vo) {
+        Integer endYearMonth = vo.getEndYearMonth();
+        List<CarNoticesPo> list = new ArrayList<>();
+        Map<String, String> map = new HashMap<>();
+        StringSubstitutor substitutor = new StringSubstitutor(map);
+        String template = "全省累计发生车辆费用${qsfy}万元,同比${tb}万元,百分比为${tbbfb},车辆费用占收比为${zsb},北十排名第${bspm},占收比较${zsbgd}。省内${zsbjgdw}分公司占收比较高。";
+        map.put("qsfy", vo.getClfy().getQsfy());
+        map.put("tb", vo.getClfy().getTb());
+        map.put("tbbfb", vo.getClfy().getTbbfb());
+        map.put("zsb", vo.getClfy().getZsb());
+        map.put("bspm", vo.getClfy().getBspm());
+        map.put("zsbgd", vo.getClfy().getZsbgd());
+        map.put("zsbjgdw", vo.getClfy().getZsbjgdw());
+        list.add(new CarNoticesPo(endYearMonth, substitutor.replace(template)));
+        map.clear();
+        template = "全省车辆违规行驶累计${qswg}次,其中${wgzddw}违规车辆次数最多,${wgzdcs}次。";
+        map.put("qswg", vo.getWgyc().getQswg());
+        map.put("wgzddw", vo.getWgyc().getWgzddw());
+        map.put("wgzdcs", vo.getWgyc().getWgzdcs());
+        list.add(new CarNoticesPo(endYearMonth, substitutor.replace(template)));
+        map.clear();
+        for (CarDxUnitVo t : vo.getCldx().getDxUnitList()) {
+            if ("合计".equals(t.getFirstUnit())) {
+                continue;
+            }
+            template = "${firstUnit}低效车占比${diXiaoPercentTy}。";
+            map.put("firstUnit", t.getFirstUnit());
+            map.put("diXiaoPercentTy", t.getDiXiaoPercentTy());
+            list.add(new CarNoticesPo(endYearMonth, t.getFirstUnit(), substitutor.replace(template)));
+            map.clear();
+        }
+        for (CarWzUnitVo t : vo.getWzclyc().getWzUnitList()) {
+            if ("总计".equals(t.getFirstUnit())) {
+                continue;
+            }
+            template = "${firstUnit}超150天未处理违章${total}条";
+            map.put("firstUnit", t.getFirstUnit());
+            map.put("total", t.getTotal());
+            list.add(new CarNoticesPo(endYearMonth, t.getFirstUnit(), substitutor.replace(template)));
+            map.clear();
+        }
+        int updateCount = carReportDao.insertBatchCarNotices(list);
+        if (updateCount == 0) {
+            throw new MyRuntimeException("插入car.notices失败");
+        }
+    }
+}

+ 3 - 0
src/main/java/com/nokia/finance/tasks/jobs/car/procedure/CarFeeProcJob.java

@@ -59,6 +59,9 @@ public class CarFeeProcJob {
             carProcedureDao.updateCarZuLin(endYearMonth);
             int update1 = carProcedureDao.updateCarFeiYongMonthYunXingFeiZongFeiYong(endYearMonth);
             int update2 = carProcedureDao.updateCarFeiYongMonthBaseInfo(endYearMonth);
+            carProcedureDao.insertCarRanYouYiChang(startYearMonth, endYearMonth);
+            carProcedureDao.insertCarZiYouWeiXiuYiChang(startYearMonth, endYearMonth);
+            carProcedureDao.insertCarZuLinWeiXiuYiChang(startYearMonth, endYearMonth);
             int update3 = gdcCarProcedureDao.insertOneCarOneTable(endYearMonth);
             if (update1 == 0 || update2 == 0 || update3 == 0) {
                 throw new MyRuntimeException("车辆费用数据加工定时任务失败");

+ 27 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarBglryQsPo.java

@@ -0,0 +1,27 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@NoArgsConstructor
+@Data
+public class CarBglryQsPo {
+    /**
+     * 月
+     */
+    private Integer monthNo;
+    /**
+     * 燃油
+     */
+    private BigDecimal tmRy;
+    /**
+     * 里程
+     */
+    private BigDecimal tmLc;
+    /**
+     * 百公里油费
+     */
+    private BigDecimal bglry;
+}

+ 31 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarBglryUnitPo.java

@@ -0,0 +1,31 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@NoArgsConstructor
+@Data
+public class CarBglryUnitPo {
+    /**
+     * 二级组织机构编码
+     */
+    private String areaNo;
+    /**
+     * 二级组织机构名称
+     */
+    private String areaName;
+    /**
+     * 燃油
+     */
+    private BigDecimal tyRy;
+    /**
+     * 里程
+     */
+    private BigDecimal tyLc;
+    /**
+     * 百公里油费
+     */
+    private BigDecimal bglry;
+}

+ 29 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarBszsbPo.java

@@ -0,0 +1,29 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class CarBszsbPo {
+    /**
+     * 省份
+     */
+    private String areaName;
+    /**
+     * 本年累计费用
+     */
+    private BigDecimal tyFy;
+    /**
+     * 本年累计收入
+     */
+    private BigDecimal tySr;
+    /**
+     * 本年占收比
+     */
+    private BigDecimal tyZsb;
+    /**
+     * 排名
+     */
+    private Integer tyZsbRank;
+}

+ 43 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarClgkPo.java

@@ -0,0 +1,43 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+@Data
+public class CarClgkPo {
+    /**
+     * 车辆总数
+     */
+    private Integer total;
+    /**
+     * 自有车辆
+     */
+    private Integer ziYouCount;
+    /**
+     * 租赁车辆
+     */
+    private Integer zuLinCount;
+    /**
+     * 生产用车
+     */
+    private Integer shengChanCount;
+    /**
+     * 公务用车
+     */
+    private Integer gongWuCount;
+    /**
+     * 皮卡车
+     */
+    private Integer piKaCount;
+    /**
+     * 微型面包车
+     */
+    private Integer weiXingMianBaoCount;
+    /**
+     * suv
+     */
+    private Integer yueYeCount;
+    /**
+     * 轿车
+     */
+    private Integer jiaoCheCount;
+}

+ 41 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarCqclqkPo.java

@@ -0,0 +1,41 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class CarCqclqkPo {
+    /**
+     * 单位
+     */
+    private String firstUnit;
+    /**
+     * 自有车辆小计
+     */
+    private Integer ziYou;
+    /**
+     * 车龄低于6年
+     */
+    private Integer lte6;
+    /**
+     * 车龄6-10年
+     */
+    private Integer gte6lte10;
+    /**
+     * 车龄10年以上
+     */
+    private Integer gt10;
+    /**
+     * 租赁车辆
+     */
+    private Integer zuLin;
+    /**
+     * 合计
+     */
+    private Integer total;
+    /**
+     * 成新率
+     */
+    private BigDecimal chengXinLv;
+}

+ 143 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarDxPo.java

@@ -0,0 +1,143 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class CarDxPo {
+    /**
+     * 数据年月
+     */
+    private Integer yearMonth;
+
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+
+    /**
+     * 当年累计行驶时长
+     */
+    private BigDecimal xingShiShiChangSum;
+
+    /**
+     * 当年累计行驶天数
+     */
+    private Integer xingShiTianShuSum;
+
+    /**
+     * 当年累计行驶里程
+     */
+    private BigDecimal zongLiChengSum;
+
+    /**
+     * 日均里程
+     */
+    private BigDecimal riJunLiChengSum;
+
+    /**
+     * 出勤率
+     */
+    private BigDecimal chuQinLvSum;
+
+    /**
+     * 当年累计工作日天数
+     */
+    private Integer workdaySum;
+
+    /**
+     * 车辆类型
+     */
+    private String cheLiangLeiXing;
+
+    /**
+     * 车辆来源
+     */
+    private String cheLiangLaiYuan;
+
+    /**
+     * 车辆使用性质
+     */
+    private String cheLiangShiYongXingZhi;
+
+    /**
+     * 车辆所属单位
+     */
+    private String cheLiangSuoShuDanWei;
+
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+
+    /**
+     * 二级单位
+     */
+    private String secondUnit;
+
+    /**
+     * 三级单位
+     */
+    private String thirdUnit;
+
+    /**
+     * 地市组织机构编码
+     */
+    private String areaNo;
+
+    /**
+     * 地市组织机构名称
+     */
+    private String areaName;
+
+    /**
+     * 区县组织机构编码
+     */
+    private String cityNo;
+
+    /**
+     * 区县组织机构名称
+     */
+    private String cityName;
+
+    /**
+     * 地市
+     */
+    private String city;
+
+    /**
+     * 区县
+     */
+    private String district;
+
+    /**
+     * 地市组织机构编码传输局用地市编码
+     */
+    private String areaName2;
+
+    /**
+     * 地市组织机构名称传输局用地市名称
+     */
+    private String areaNo2;
+
+    /**
+     * 年
+     */
+    private Integer yearNo;
+
+    /**
+     * 月
+     */
+    private Integer monthNo;
+
+    /**
+     * 地市id
+     */
+    private String cityId;
+
+    /**
+     * 区县id
+     */
+    private String districtId;
+}

+ 43 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarDxUnitPo.java

@@ -0,0 +1,43 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@NoArgsConstructor
+@Data
+public class CarDxUnitPo {
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 去年车数
+     */
+    private Integer totalLy;
+    /**
+     * 去年低效车数
+     */
+    private Integer diXiaoCountLy;
+    /**
+     * 去年低效占比
+     */
+    private BigDecimal diXiaoPercentLy;
+    /**
+     * 今年车数
+     */
+    private Integer totalTy;
+    /**
+     * 今年低效车数
+     */
+    private Integer diXiaoCountTy;
+    /**
+     * 今年低效占比
+     */
+    private BigDecimal diXiaoPercentTy;
+    /**
+     * 低效占比变化
+     */
+    private BigDecimal diXiaoChange;
+}

+ 58 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarJygxPo.java

@@ -0,0 +1,58 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@Data
+public class CarJygxPo {
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+    /**
+     * 车辆品牌
+     */
+    private String cheLiangPinPai;
+    /**
+     * 登记日期
+     */
+    private LocalDate dengJiRiQi;
+    /**
+     * 车辆来源
+     */
+    private String cheLiangLaiYuan;
+    /**
+     * 车辆类型
+     */
+    private String cheLiangLeiXing;
+    /**
+     * 车辆使用性质
+     */
+    private String cheLiangShiYongXingZhi;
+    /**
+     * 车辆所属单位
+     */
+    private String cheLiangSuoShuDanWei;
+    /**
+     * 一级
+     */
+    private String firstUnit;
+    /**
+     * 二级
+     */
+    private String secondUnit;
+    /**
+     * 三级
+     */
+    private String thirdUnit;
+    /**
+     * 车龄
+     */
+    private Integer cheLing;
+    /**
+     * 累计维修
+     */
+    private BigDecimal weiXiuSum;
+}

+ 39 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarJygxUnitPo.java

@@ -0,0 +1,39 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+@Data
+public class CarJygxUnitPo {
+    /**
+     * 单位
+     */
+    private String firstUnit;
+    /**
+     * 轿车
+     */
+    private Integer jc;
+    /**
+     * 皮卡车
+     */
+    private Integer pkc;
+    /**
+     * 商务车
+     */
+    private Integer swc;
+    /**
+     * 特种车
+     */
+    private Integer tzc;
+    /**
+     * 越野车
+     */
+    private Integer yyc;
+    /**
+     * 中型面包车(8-20座的面包车)
+     */
+    private Integer zxmbc;
+    /**
+     * 总计
+     */
+    private Integer total;
+}

+ 44 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarNoticesPo.java

@@ -0,0 +1,44 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@NoArgsConstructor
+public class CarNoticesPo {
+    /**
+     * 账期
+     */
+    private Integer yearMonth;
+
+    /**
+     * 地市
+     */
+    private String city;
+
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    public CarNoticesPo(Integer yearMonth, String content) {
+        this.yearMonth = yearMonth;
+        this.city = "全省";
+        this.content = content;
+        this.createTime = LocalDateTime.now();
+    }
+
+    public CarNoticesPo(Integer yearMonth, String city, String content) {
+        this.yearMonth = yearMonth;
+        this.city = city;
+        this.content = content;
+        this.createTime = LocalDateTime.now();
+    }
+}

+ 21 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarReportsPo.java

@@ -0,0 +1,21 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+@Data
+public class CarReportsPo {
+    /**
+     * 报告年月
+     */
+    private Integer yearMonth;
+
+    /**
+     * 文件类型
+     */
+    private String fileType;
+
+    /**
+     * 报告url
+     */
+    private String url;
+}

+ 92 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarRyycPo.java

@@ -0,0 +1,92 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@NoArgsConstructor
+@Data
+public class CarRyycPo {
+    /**
+     * 账期
+     */
+    private Integer yearMonth;
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+    /**
+     * 一级
+     */
+    private String firstUnit;
+    /**
+     * 二级
+     */
+    private String secondUnit;
+    /**
+     * 三级
+     */
+    private String thirdUnit;
+    /**
+     * 车辆所属单位
+     */
+    private String cheLiangSuoShuDanWei;
+    /**
+     * 车辆来源
+     */
+    private String cheLiangLaiYuan;
+    /**
+     * 车辆类型
+     */
+    private String cheLiangLeiXing;
+    /**
+     * 车辆使用性质
+     */
+    private String cheLiangShiYongXingZhi;
+    /**
+     * 燃油
+     */
+    private BigDecimal ranYouSum;
+    /**
+     * 里程
+     */
+    private BigDecimal zongLiChengSum;
+    /**
+     * 百公里油费
+     */
+    private BigDecimal baiGongLiYouFei;
+    /**
+     * 百公里油耗
+     */
+    private BigDecimal baiGongLiYouHao;
+    /**
+     * 百公里油费排名
+     */
+    private Integer baiGongLiYouFeiRank;
+    /**
+     * 二级组织机构编码
+     */
+    private String areaNo;
+    /**
+     * 二级组织机构名称
+     */
+    private String areaName;
+    /**
+     * 三级组织机构编码
+     */
+    private String cityNo;
+    /**
+     * 三级组织机构名称
+     */
+    private String cityName;
+    /**
+     * 登记日期
+     */
+    private LocalDate dengJiRiQi;
+    /**
+     * 车龄
+     */
+    private BigDecimal cheLing;
+}

+ 15 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarRyycUnitPo.java

@@ -0,0 +1,15 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+@Data
+public class CarRyycUnitPo {
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 车数
+     */
+    private Integer total;
+}

+ 61 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarSnfyPo.java

@@ -0,0 +1,61 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class CarSnfyPo {
+    /**
+     * 年
+     */
+    private Integer yearNo;
+    /**
+     * 月
+     */
+    private Integer monthNo;
+    /**
+     * 二级组织机构编码
+     */
+    private String secondOrgNo;
+    /**
+     * 二级组织机构名称
+     */
+    private String secondOrgName;
+    /**
+     * 本年
+     */
+    private BigDecimal tyFy;
+    /**
+     * 上年
+     */
+    private BigDecimal lyFy;
+    /**
+     * 预算累计
+     */
+    private BigDecimal budgetLj;
+    /**
+     * 同比增减
+     */
+    private BigDecimal tbzj;
+    /**
+     * 同比百分比
+     */
+    private BigDecimal tbbfb;
+    /**
+     * 预算偏差
+     */
+    private BigDecimal yspc;
+    /**
+     * 偏差百分比
+     */
+    private BigDecimal yspcbfb;
+    /**
+     * 本年累计收入
+     */
+    private BigDecimal tySr;
+    /**
+     * 本年占收比
+     */
+    private BigDecimal tyZsb;
+}

+ 93 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWgPo.java

@@ -0,0 +1,93 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class CarWgPo {
+    /**
+     * 车辆所属单位
+     */
+    private String cheLiangSuoShuDanWei;
+
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+
+    /**
+     * 车辆类型
+     */
+    private String cheLiangLeiXing;
+
+    /**
+     * 车辆使用性质
+     */
+    private String cheLiangShiYongXingZhi;
+
+    /**
+     * 报警区域描述
+     */
+    private String baoJingQuYuMiaoShu;
+
+    /**
+     * 报警规则描述
+     */
+    private String baoJingGuiZeMiaoShu;
+
+    /**
+     * 越界时间
+     */
+    private LocalDateTime yueJieShiJian;
+
+    /**
+     * 是否执行中越界
+     */
+    private String shiFouZhiXingZhongYueJie;
+
+    /**
+     * 详情
+     */
+    private String xiangQing;
+
+    /**
+     * 地市
+     */
+    private String firstUnit;
+
+    /**
+     * 二级单位
+     */
+    private String secondUnit;
+
+    /**
+     * 网格
+     */
+    private String thirdUnit;
+
+    /**
+     * 数据年月
+     */
+    private Integer yearMonth;
+
+    /**
+     * 地市组织机构编码
+     */
+    private String areaNo;
+
+    /**
+     * 地市组织机构名称
+     */
+    private String areaName;
+
+    /**
+     * 区县组织机构编码
+     */
+    private String cityNo;
+
+    /**
+     * 区县组织机构名称
+     */
+    private String cityName;
+}

+ 19 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWxQsPo.java

@@ -0,0 +1,19 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@NoArgsConstructor
+@Data
+public class CarWxQsPo {
+    /**
+     * 月
+     */
+    private Integer monthNo;
+    /**
+     * 维修
+     */
+    private BigDecimal tmWx;
+}

+ 31 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWxUnitPo.java

@@ -0,0 +1,31 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@NoArgsConstructor
+@Data
+public class CarWxUnitPo {
+    /**
+     * 二级组织机构编码
+     */
+    private String areaNo;
+    /**
+     * 二级组织机构名称
+     */
+    private String areaName;
+    /**
+     * 维修费
+     */
+    private BigDecimal tyWx;
+    /**
+     * 自有车辆数
+     */
+    private Integer total;
+    /**
+     * 单车维修费
+     */
+    private BigDecimal tyWxAvg;
+}

+ 89 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWzPo.java

@@ -0,0 +1,89 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+public class CarWzPo {
+    /**
+     * 数据年月
+     */
+    private Integer yearMonth;
+
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+
+    /**
+     * 违章时间
+     */
+    private LocalDateTime weiZhangShiJian;
+
+    /**
+     * 违章地点
+     */
+    private String weiZhangDiDian;
+
+    /**
+     * 违章详情
+     */
+    private String weiZhangXiangQing;
+
+    /**
+     * 扣分
+     */
+    private Integer kouFen;
+
+    /**
+     * 罚款
+     */
+    private BigDecimal faKuan;
+
+    /**
+     * 处理状态
+     */
+    private String chuLiZhuangTai;
+
+    /**
+     * 违章未处理时长(天)
+     */
+    private Integer weiZhangWeiChuLiShiChang;
+
+    /**
+     * 地市
+     */
+    private String firstUnit;
+
+    /**
+     * 二级单位
+     */
+    private String secondUnit;
+
+    /**
+     * 网格
+     */
+    private String thirdUnit;
+
+    /**
+     * 地市组织机构编码
+     */
+    private String areaNo;
+
+    /**
+     * 地市组织机构名称
+     */
+    private String areaName;
+
+    /**
+     * 区县组织机构编码
+     */
+    private String cityNo;
+
+    /**
+     * 区县组织机构名称
+     */
+    private String cityName;
+}

+ 15 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarWzUnitPo.java

@@ -0,0 +1,15 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+@Data
+public class CarWzUnitPo {
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 违章次数
+     */
+    private Integer total;
+}

+ 80 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarZlwxycPo.java

@@ -0,0 +1,80 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@NoArgsConstructor
+@Data
+public class CarZlwxycPo {
+    /**
+     * 账期
+     */
+    private Integer yearMonth;
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+    /**
+     * 一级
+     */
+    private String firstUnit;
+    /**
+     * 二级
+     */
+    private String secondUnit;
+    /**
+     * 三级
+     */
+    private String thirdUnit;
+    /**
+     * 车辆所属单位
+     */
+    private String cheLiangSuoShuDanWei;
+    /**
+     * 车辆来源
+     */
+    private String cheLiangLaiYuan;
+    /**
+     * 车辆类型
+     */
+    private String cheLiangLeiXing;
+    /**
+     * 车辆使用性质
+     */
+    private String cheLiangShiYongXingZhi;
+    /**
+     * 累计维修
+     */
+    private BigDecimal weiXiuSum;
+    /**
+     * 排名
+     */
+    private Integer weiXiuRank;
+    /**
+     * 登记日期
+     */
+    private LocalDate dengJiRiQi;
+    /**
+     * 车龄
+     */
+    private BigDecimal cheLing;
+    /**
+     * 二级组织机构编码
+     */
+    private String areaNo;
+    /**
+     * 二级组织机构名称
+     */
+    private String areaName;
+    /**
+     * 三级组织机构编码
+     */
+    private String cityNo;
+    /**
+     * 三级组织机构名称
+     */
+    private String cityName;
+}

+ 80 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarZywxycPo.java

@@ -0,0 +1,80 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@NoArgsConstructor
+@Data
+public class CarZywxycPo {
+    /**
+     * 账期
+     */
+    private Integer yearMonth;
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+    /**
+     * 一级
+     */
+    private String firstUnit;
+    /**
+     * 二级
+     */
+    private String secondUnit;
+    /**
+     * 三级
+     */
+    private String thirdUnit;
+    /**
+     * 车辆所属单位
+     */
+    private String cheLiangSuoShuDanWei;
+    /**
+     * 车辆来源
+     */
+    private String cheLiangLaiYuan;
+    /**
+     * 车辆类型
+     */
+    private String cheLiangLeiXing;
+    /**
+     * 车辆使用性质
+     */
+    private String cheLiangShiYongXingZhi;
+    /**
+     * 累计维修
+     */
+    private BigDecimal weiXiuSum;
+    /**
+     * 排名
+     */
+    private Integer weiXiuRank;
+    /**
+     * 登记日期
+     */
+    private LocalDate dengJiRiQi;
+    /**
+     * 车龄
+     */
+    private BigDecimal cheLing;
+    /**
+     * 二级组织机构编码
+     */
+    private String areaNo;
+    /**
+     * 二级组织机构名称
+     */
+    private String areaName;
+    /**
+     * 三级组织机构编码
+     */
+    private String cityNo;
+    /**
+     * 三级组织机构名称
+     */
+    private String cityName;
+}

+ 15 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/car_report/CarZywxycUnitPo.java

@@ -0,0 +1,15 @@
+package com.nokia.finance.tasks.pojo.po.car_report;
+
+import lombok.Data;
+
+@Data
+public class CarZywxycUnitPo {
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 车数
+     */
+    private Integer total;
+}

+ 18 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarBglryQsVo.java

@@ -0,0 +1,18 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryQsPo;
+import lombok.Data;
+
+@Data
+public class CarBglryQsVo {
+    private String idx;
+    /**
+     * 百公里油费
+     */
+    private String val;
+
+    public CarBglryQsVo(CarBglryQsPo carBglryQsPo) {
+        this.idx = String.valueOf(carBglryQsPo.getMonthNo() -1);
+        this.val = carBglryQsPo.getBglry().toString();
+    }
+}

+ 23 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarBglryUnitVo.java

@@ -0,0 +1,23 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryUnitPo;
+import lombok.Data;
+
+@Data
+public class CarBglryUnitVo {
+    private String idx;
+    /**
+     * 二级组织机构
+     */
+    private String cat;
+    /**
+     * 百公里燃油
+     */
+    private String val;
+
+    public CarBglryUnitVo(String idx, CarBglryUnitPo carBglryUnitPo) {
+        this.idx = idx;
+        this.cat = carBglryUnitPo.getAreaName();
+        this.val = carBglryUnitPo.getBglry().toString();
+    }
+}

+ 23 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarBszsbVo.java

@@ -0,0 +1,23 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarBszsbPo;
+import lombok.Data;
+
+@Data
+public class CarBszsbVo {
+    private String idx;
+    /**
+     * 省份
+     */
+    private String cat;
+    /**
+     * 本年占收比
+     */
+    private String val;
+
+    public CarBszsbVo(String idx, CarBszsbPo carBszsbPo) {
+        this.idx = idx;
+        this.cat = carBszsbPo.getAreaName();
+        this.val = carBszsbPo.getTyZsb().toString();
+    }
+}

+ 172 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarCldxVo.java

@@ -0,0 +1,172 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.config.CarReportConfig;
+import com.nokia.finance.tasks.pojo.po.car_report.CarDxPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarDxUnitPo;
+import lombok.Data;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Stream;
+
+@Data
+public class CarCldxVo {
+    /**
+     * 低效车辆一级单位统计
+     */
+    private List<CarDxUnitVo> dxUnitList;
+
+    public CarCldxVo(List<CarDxUnitPo> dxUnitList, List<CarDxPo> carDxPoList, CarReportConfig carReportConfig)
+            throws IOException {
+        this.dxUnitList = new ArrayList<>();
+        List<String> unitList = Stream.of("石家庄", "唐山", "秦皇岛", "邯郸", "邢台", "保定", "张家口", "承德",
+                "廊坊", "沧州", "衡水", "雄安", "机动局", "合计").toList();
+        int unitListSize = unitList.size();
+        int dxUnitListSize = dxUnitList.size();
+        if (dxUnitListSize == 1) {
+            for (int i = 0; i < unitListSize; i++) {
+                String firstUnit = unitList.get(i);
+                CarDxUnitVo carDxUnitVo = new CarDxUnitVo(String.valueOf(i + 1), firstUnit);
+                this.dxUnitList.add(carDxUnitVo);
+            }
+        } else {
+            for (int i = 0; i < unitListSize; i++) {
+                String firstUnit = unitList.get(i);
+                CarDxUnitVo carDxUnitVo = new CarDxUnitVo(i + 1, firstUnit);
+                this.dxUnitList.add(carDxUnitVo);
+                for (CarDxUnitPo carDxUnitPo : dxUnitList) {
+                    if (firstUnit.equals(carDxUnitPo.getFirstUnit())) {
+                        carDxUnitVo.update(carDxUnitPo);
+                        break;
+                    }
+                }
+            }
+        }
+        writeDxXlsx(carDxPoList, carReportConfig);
+    }
+
+    /**
+     * 低效车辆xlsx
+     */
+    private void writeDxXlsx(List<CarDxPo> carDxPoList, CarReportConfig carReportConfig) throws IOException {
+        try (SXSSFWorkbook wb = new SXSSFWorkbook();
+//             FastByteArrayOutputStream os = new FastByteArrayOutputStream()
+             OutputStream os = Files.newOutputStream(Paths.get(carReportConfig.getDxXlsx()))
+        ) {
+            DataFormat dataFormat = wb.createDataFormat();
+            // 数字样式
+            CellStyle numberCellStyle = wb.createCellStyle();
+            numberCellStyle.setDataFormat(dataFormat.getFormat("#,##0.00"));
+            numberCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 百分比样式
+            CellStyle percentCellStyle = wb.createCellStyle();
+            percentCellStyle.setDataFormat(dataFormat.getFormat("0.00%"));
+            percentCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 表头样式
+            CellStyle headerCellStyle = wb.createCellStyle();
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            SXSSFSheet sheet = wb.createSheet();
+            AtomicInteger rowIndex = new AtomicInteger(0);
+            // 表头
+            Row headerRow = sheet.createRow(rowIndex.getAndIncrement());
+            List<String> headers = Stream.of("车牌号", "单位", "二级", "三级", "车辆所属单位", "车辆来源", "车辆类型",
+                    "车辆使用性质", "日均里程", "出勤率", "总里程", "行驶天数", "工作日天数").toList();
+            int headerSize = headers.size();
+            for (int i = 0; i < headerSize; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers.get(i));
+                cell.setCellStyle(headerCellStyle);
+                // 根据内容长度设置列宽
+                int columnWidth = headers.get(i).length() * 256 * 2 + 256 * 5;
+                sheet.setColumnWidth(i, columnWidth);
+            }
+            for (CarDxPo t : carDxPoList) {
+                AtomicInteger columnIndex = new AtomicInteger(0);
+                Row row = sheet.createRow(rowIndex.getAndIncrement());
+                // 车牌号
+                Cell chePaiHaoCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChePaiHao() != null) {
+                    chePaiHaoCell.setCellValue(t.getChePaiHao());
+                }
+                // 单位
+                Cell firstUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getFirstUnit() != null) {
+                    firstUnitCell.setCellValue(t.getFirstUnit());
+                }
+                // 二级
+                Cell secondUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getSecondUnit() != null) {
+                    secondUnitCell.setCellValue(t.getSecondUnit());
+                }
+                // 三级
+                Cell thirdUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getThirdUnit() != null) {
+                    thirdUnitCell.setCellValue(t.getThirdUnit());
+                }
+                // 车辆所属单位
+                Cell cheLiangSuoShuDanWeiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangSuoShuDanWei() != null) {
+                    cheLiangSuoShuDanWeiCell.setCellValue(t.getCheLiangSuoShuDanWei());
+                }
+                // 车辆来源
+                Cell cheLiangLaiYuanCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLaiYuan() != null) {
+                    cheLiangLaiYuanCell.setCellValue(t.getCheLiangLaiYuan());
+                }
+                // 车辆类型
+                Cell cheLiangLeiXingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLeiXing() != null) {
+                    cheLiangLeiXingCell.setCellValue(t.getCheLiangLeiXing());
+                }
+                // 车辆使用性质
+                Cell cheLiangShiYongXingZhiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangShiYongXingZhi() != null) {
+                    cheLiangShiYongXingZhiCell.setCellValue(t.getCheLiangShiYongXingZhi());
+                }
+                // 日均里程
+                Cell riJunLiChengSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getRiJunLiChengSum() != null) {
+                    riJunLiChengSumCell.setCellValue(t.getRiJunLiChengSum().doubleValue());
+                }
+                riJunLiChengSumCell.setCellStyle(numberCellStyle);
+                // 出勤率
+                Cell chuQinLvSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChuQinLvSum() != null) {
+                    chuQinLvSumCell.setCellValue(t.getChuQinLvSum().doubleValue());
+                }
+                chuQinLvSumCell.setCellStyle(percentCellStyle);
+                // 总里程
+                Cell zongLiChengSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getZongLiChengSum() != null) {
+                    zongLiChengSumCell.setCellValue(t.getZongLiChengSum().doubleValue());
+                }
+                zongLiChengSumCell.setCellStyle(numberCellStyle);
+                // 行驶天数
+                Cell xingShiTianShuSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getXingShiTianShuSum() != null) {
+                    xingShiTianShuSumCell.setCellValue(t.getXingShiTianShuSum());
+                }
+                // 工作日天数
+                Cell workdaySumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWorkdaySum() != null) {
+                    workdaySumCell.setCellValue(t.getWorkdaySum());
+                }
+            }
+            wb.write(os);
+        }
+    }
+}

+ 159 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarClfyVo.java

@@ -0,0 +1,159 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryQsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarBglryUnitPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarBszsbPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarSnfyPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxQsPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxUnitPo;
+import lombok.Data;
+import org.springframework.util.CollectionUtils;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Data
+public class CarClfyVo {
+    /**
+     * 全省累计发生车辆费用万元
+     */
+    private String qsfy;
+    /**
+     * 全省费用同比增减万元
+     */
+    private String tb;
+    /**
+     * 全省费用同比增减百分比
+     */
+    private String tbbfb;
+    /**
+     * 占收比
+     */
+    private String zsb;
+    /**
+     * 北十排名
+     */
+    private String bspm;
+    /**
+     * 占收比高低
+     */
+    private String zsbgd;
+    /**
+     * 占收比较高单位
+     */
+    private String zsbjgdw;
+    /**
+     * 省内车辆费用
+     */
+    private List<CarSnfyVo> snfyList;
+    /**
+     * 北十车辆费用占收比对标
+     */
+    private List<CarBszsbVo> bszsbList;
+    /**
+     * 1-12月百公里燃油费变化情况
+     */
+    private List<CarBglryQsVo> bglryQsList;
+    /**
+     * 二级组织机构百公里燃油
+     */
+    private List<CarBglryUnitVo> bglryUnitList;
+    /**
+     * 1-12月维修费变化情况
+     */
+    private List<CarWxQsVo> wxQsList;
+    /**
+     * 二级组织机构自有车辆单车维修费
+     */
+    private List<CarWxUnitVo> wxUnitList;
+
+    public CarClfyVo(List<CarSnfyPo> snfyList, List<CarBszsbPo> bszsbList, List<CarBglryQsPo> bglryQsList,
+                     List<CarBglryUnitPo> bglryUnitList, List<CarWxQsPo> wxQsList, List<CarWxUnitPo> wxUnitList) {
+        this.snfyList = new ArrayList<>();
+        this.bszsbList = new ArrayList<>();
+        this.bglryQsList = new ArrayList<>();
+        this.bglryUnitList = new ArrayList<>();
+        this.wxQsList = new ArrayList<>();
+        this.wxUnitList = new ArrayList<>();
+        List<String> unitList = Stream.of("石家庄", "唐山", "秦皇岛", "邯郸", "邢台", "保定", "张家口", "承德",
+                "廊坊", "沧州", "衡水", "雄安", "传输局", "省本部", "合计").toList();
+        int unitListSize = unitList.size();
+        int snfyListSize = snfyList.size();
+        if (snfyListSize == 1) {
+            this.qsfy = CarReportVo.PLACEHOLDER;
+            this.tb = CarReportVo.PLACEHOLDER;
+            this.tbbfb = CarReportVo.PLACEHOLDER;
+            this.zsbjgdw = CarReportVo.PLACEHOLDER;
+            for (int i = 0; i < unitListSize; i++) {
+                String firstUnit = unitList.get(i);
+                CarSnfyVo carSnfyVo = new CarSnfyVo(String.valueOf(i + 1), firstUnit);
+                this.snfyList.add(carSnfyVo);
+            }
+        } else {
+            DecimalFormat integerFormat = new DecimalFormat("#,###");
+            BigDecimal qsTyZsb = BigDecimal.ZERO;
+            for (int i = 0; i < unitListSize; i++) {
+                String firstUnit = unitList.get(i);
+                CarSnfyVo carSnfyVo = new CarSnfyVo(i + 1, firstUnit);
+                this.snfyList.add(carSnfyVo);
+                for (CarSnfyPo carSnfyPo : snfyList) {
+                    if (firstUnit.equals(carSnfyPo.getSecondOrgName())) {
+                        carSnfyVo.update(carSnfyPo);
+                        if ("合计".equals(carSnfyPo.getSecondOrgName())) {
+                            qsTyZsb = carSnfyPo.getTyZsb();
+                            this.qsfy = integerFormat.format(carSnfyPo.getTyFy());
+                            BigDecimal tbzj = carSnfyPo.getTbzj();
+                            this.tb = (tbzj.compareTo(BigDecimal.ZERO) >= 0 ? "增加" : "减少")
+                                    + integerFormat.format(tbzj.abs());
+                            this.tbbfb = carSnfyVo.getTbbfb();
+                        }
+                        break;
+                    }
+                }
+            }
+            BigDecimal finalQsTyZsb = qsTyZsb;
+            this.zsbjgdw = snfyList.stream()
+                    .filter(t -> !t.getSecondOrgName().equals("合计")
+                            && t.getTyZsb() != null
+                            && t.getTyZsb().compareTo(finalQsTyZsb) > 0)
+                    .map(CarSnfyPo::getSecondOrgName).collect(Collectors.joining("、"));
+        }
+        if (CollectionUtils.isEmpty(bszsbList)) {
+            this.zsb = CarReportVo.PLACEHOLDER;
+            this.bspm = CarReportVo.PLACEHOLDER;
+            this.zsbgd = CarReportVo.PLACEHOLDER;
+        } else {
+            int bszsbListSize = bszsbList.size();
+            for (int i = 0; i < bszsbListSize; i++) {
+                CarBszsbPo carBszsbPo = bszsbList.get(i);
+                this.bszsbList.add(new CarBszsbVo(String.valueOf(i), carBszsbPo));
+                if ("河北".equals(carBszsbPo.getAreaName())) {
+                    DecimalFormat percentFormat = new DecimalFormat("0.000%");
+                    this.zsb = percentFormat.format(carBszsbPo.getTyZsb());
+                    this.bspm = carBszsbPo.getTyZsbRank().toString();
+                    this.zsbgd = carBszsbPo.getTyZsbRank().compareTo(5) <= 0 ? "高" : "低";
+                }
+            }
+        }
+        for (CarBglryQsPo carBglryQsPo : bglryQsList) {
+            this.bglryQsList.add(new CarBglryQsVo(carBglryQsPo));
+        }
+        int bglryUnitListSize = bglryUnitList.size();
+        for (int i = 0; i < bglryUnitListSize; i++) {
+            CarBglryUnitPo carBglryUnitPo = bglryUnitList.get(i);
+            this.bglryUnitList.add(new CarBglryUnitVo(String.valueOf(i), carBglryUnitPo));
+        }
+        for (CarWxQsPo carWxQsPo : wxQsList) {
+            this.wxQsList.add(new CarWxQsVo(carWxQsPo));
+        }
+        int wxUnitListSize = wxUnitList.size();
+        for (int i = 0; i < wxUnitListSize; i++) {
+            CarWxUnitPo carWxUnitPo = wxUnitList.get(i);
+            this.wxUnitList.add(new CarWxUnitVo(String.valueOf(i), carWxUnitPo));
+        }
+    }
+}

+ 243 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarClgkVo.java

@@ -0,0 +1,243 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.config.CarReportConfig;
+import com.nokia.finance.tasks.pojo.po.car_report.CarClgkPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarCqclqkPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarJygxPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarJygxUnitPo;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Stream;
+
+@Data
+@NoArgsConstructor
+public class CarClgkVo {
+    /**
+     * 车辆总数
+     */
+    private String total;
+    /**
+     * 自有车辆
+     */
+    private String ziYouCount;
+    /**
+     * 租赁车辆
+     */
+    private String zuLinCount;
+    /**
+     * 生产用车
+     */
+    private String shengChanCount;
+    /**
+     * 公务用车
+     */
+    private String gongWuCount;
+    /**
+     * 皮卡车
+     */
+    private String piKaCount;
+    /**
+     * 微型面包车
+     */
+    private String weiXingMianBaoCount;
+    /**
+     * suv
+     */
+    private String yueYeCount;
+    /**
+     * 轿车
+     */
+    private String jiaoCheCount;
+    /**
+     * 成新率
+     */
+    private String chengXinLv;
+    /**
+     * 产权车龄情况
+     */
+    private List<CarCqclqkVo> cqclqkList;
+    /**
+     * 建议更新车辆一级单位统计
+     */
+    private List<CarJygxUnitVo> jygxUnitList;
+
+    public CarClgkVo(CarClgkPo carClgkPo, List<CarCqclqkPo> carCqclqkPoList, List<CarJygxUnitPo> carJygxUnitPoList,
+                     List<CarJygxPo> carJygxPoList, CarReportConfig carReportConfig) throws IOException {
+        this.cqclqkList = new ArrayList<>();
+        this.jygxUnitList = new ArrayList<>();
+        List<String> unitList = Stream.of("石家庄", "唐山", "秦皇岛", "邯郸", "邢台", "保定", "张家口", "承德", "廊坊",
+                "沧州", "衡水", "雄安", "机动局", "省公司本部", "雄安基地建设部", "华北基地建设部", "合计").toList();
+        int unitListSize = unitList.size();
+        if (carClgkPo.getTotal().equals(0)) {
+            this.total = CarReportVo.PLACEHOLDER;
+            this.ziYouCount = CarReportVo.PLACEHOLDER;
+            this.zuLinCount = CarReportVo.PLACEHOLDER;
+            this.shengChanCount = CarReportVo.PLACEHOLDER;
+            this.gongWuCount = CarReportVo.PLACEHOLDER;
+            this.piKaCount = CarReportVo.PLACEHOLDER;
+            this.weiXingMianBaoCount = CarReportVo.PLACEHOLDER;
+            this.yueYeCount = CarReportVo.PLACEHOLDER;
+            this.jiaoCheCount = CarReportVo.PLACEHOLDER;
+            this.chengXinLv = CarReportVo.PLACEHOLDER;
+            for (int i = 0; i < unitListSize; i++) {
+                String firstUnit = unitList.get(i);
+                CarCqclqkVo carCqclqkVo = new CarCqclqkVo(String.valueOf(i + 1), firstUnit);
+                this.cqclqkList.add(carCqclqkVo);
+            }
+            this.jygxUnitList.add(new CarJygxUnitVo());
+        } else {
+            DecimalFormat integerFormat = new DecimalFormat("#,###");
+            this.total = integerFormat.format(carClgkPo.getTotal());
+            this.ziYouCount = integerFormat.format(carClgkPo.getZiYouCount());
+            this.zuLinCount = integerFormat.format(carClgkPo.getZuLinCount());
+            this.shengChanCount = integerFormat.format(carClgkPo.getShengChanCount());
+            this.gongWuCount = integerFormat.format(carClgkPo.getGongWuCount());
+            this.piKaCount = integerFormat.format(carClgkPo.getPiKaCount());
+            this.weiXingMianBaoCount = integerFormat.format(carClgkPo.getWeiXingMianBaoCount());
+            this.yueYeCount = integerFormat.format(carClgkPo.getYueYeCount());
+            this.jiaoCheCount = integerFormat.format(carClgkPo.getJiaoCheCount());
+            for (int i = 0; i < unitListSize; i++) {
+                String firstUnit = unitList.get(i);
+                CarCqclqkVo carCqclqkVo = new CarCqclqkVo(i + 1, firstUnit);
+                this.cqclqkList.add(carCqclqkVo);
+                for (CarCqclqkPo carCqclqkPo : carCqclqkPoList) {
+                    if (firstUnit.equals(carCqclqkPo.getFirstUnit())) {
+                        carCqclqkVo.update(carCqclqkPo);
+                        break;
+                    }
+                }
+                if ("合计".equals(firstUnit)) {
+                    chengXinLv = carCqclqkVo.getChengXinLv();
+                }
+            }
+            carJygxUnitPoList.forEach(t -> this.jygxUnitList.add(new CarJygxUnitVo(t)));
+        }
+        writeJygxXlsx(carJygxPoList, carReportConfig);
+    }
+
+    /**
+     * 建议更新车辆明细xlsx
+     */
+    private void writeJygxXlsx(List<CarJygxPo> carJygxPoList, CarReportConfig carReportConfig) throws IOException {
+        try (SXSSFWorkbook wb = new SXSSFWorkbook();
+//             FastByteArrayOutputStream os = new FastByteArrayOutputStream()
+             OutputStream os = Files.newOutputStream(Paths.get(carReportConfig.getJygxXlsx()))
+        ) {
+            DataFormat dataFormat = wb.createDataFormat();
+            // 数字样式
+            CellStyle numberCellStyle = wb.createCellStyle();
+            numberCellStyle.setDataFormat(dataFormat.getFormat("#,##0.00"));
+            numberCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 整数样式
+            CellStyle integerCellStyle = wb.createCellStyle();
+            integerCellStyle.setDataFormat(dataFormat.getFormat("#,##0"));
+            integerCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 日期样式
+            CellStyle dateCellStyle = wb.createCellStyle();
+            dateCellStyle.setDataFormat(dataFormat.getFormat("yyyy/MM/dd"));
+            // 表头样式
+            CellStyle headerCellStyle = wb.createCellStyle();
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            SXSSFSheet sheet = wb.createSheet();
+            AtomicInteger rowIndex = new AtomicInteger(0);
+            // 表头
+            Row headerRow = sheet.createRow(rowIndex.getAndIncrement());
+            List<String> headers = Stream.of("车牌号", "车辆品牌", "登记日期", "车辆来源", "车辆类型",
+                    "车辆使用性质", "车辆所属单位", "单位", "二级", "三级", "车龄", "维修累计").toList();
+            int headerSize = headers.size();
+            for (int i = 0; i < headerSize; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers.get(i));
+                cell.setCellStyle(headerCellStyle);
+                // 根据内容长度设置列宽
+                int columnWidth = headers.get(i).length() * 256 * 2 + 256 * 4;
+                sheet.setColumnWidth(i, columnWidth);
+            }
+            for (CarJygxPo t : carJygxPoList) {
+                AtomicInteger columnIndex = new AtomicInteger(0);
+                Row row = sheet.createRow(rowIndex.getAndIncrement());
+                // 车牌号
+                Cell chePaiHaoCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChePaiHao() != null) {
+                    chePaiHaoCell.setCellValue(t.getChePaiHao());
+                }
+                // 车辆品牌
+                Cell cheLiangPinPaiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangPinPai() != null) {
+                    cheLiangPinPaiCell.setCellValue(t.getCheLiangPinPai());
+                }
+                // 登记日期
+                Cell dengJiRiQiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getDengJiRiQi() != null) {
+                    dengJiRiQiCell.setCellValue(t.getDengJiRiQi());
+                }
+                dengJiRiQiCell.setCellStyle(dateCellStyle);
+                // 车辆来源
+                Cell cheLiangLaiYuanCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLaiYuan() != null) {
+                    cheLiangLaiYuanCell.setCellValue(t.getCheLiangLaiYuan());
+                }
+                // 车辆类型
+                Cell cheLiangLeiXingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLeiXing() != null) {
+                    cheLiangLeiXingCell.setCellValue(t.getCheLiangLeiXing());
+                }
+                // 车辆使用性质
+                Cell cheLiangShiYongXingZhiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangShiYongXingZhi() != null) {
+                    cheLiangShiYongXingZhiCell.setCellValue(t.getCheLiangShiYongXingZhi());
+                }
+                // 车辆所属单位
+                Cell cheLiangSuoShuDanWeiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangSuoShuDanWei() != null) {
+                    cheLiangSuoShuDanWeiCell.setCellValue(t.getCheLiangSuoShuDanWei());
+                }
+                // 单位
+                Cell firstUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getFirstUnit() != null) {
+                    firstUnitCell.setCellValue(t.getFirstUnit());
+                }
+                // 二级
+                Cell secondUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getSecondUnit() != null) {
+                    secondUnitCell.setCellValue(t.getSecondUnit());
+                }
+                // 三级
+                Cell thirdUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getThirdUnit() != null) {
+                    thirdUnitCell.setCellValue(t.getThirdUnit());
+                }
+                // 车龄
+                Cell cheLingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLing() != null) {
+                    cheLingCell.setCellValue(t.getCheLing());
+                }
+                // 维修累计
+                Cell weiXiuSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWeiXiuSum() != null) {
+                    weiXiuSumCell.setCellValue(t.getWeiXiuSum().doubleValue());
+                }
+                weiXiuSumCell.setCellStyle(numberCellStyle);
+            }
+            wb.write(os);
+        }
+    }
+}

+ 82 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarCqclqkVo.java

@@ -0,0 +1,82 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarCqclqkPo;
+import lombok.Data;
+
+import java.text.DecimalFormat;
+
+@Data
+public class CarCqclqkVo {
+    /**
+     * 序号
+     */
+    private String num;
+    /**
+     * 单位
+     */
+    private String firstUnit;
+    /**
+     * 自有车辆小计
+     */
+    private String ziYou;
+    /**
+     * 车龄低于6年
+     */
+    private String lte6;
+    /**
+     * 车龄6-10年
+     */
+    private String gte6lte10;
+    /**
+     * 车龄10年以上
+     */
+    private String gt10;
+    /**
+     * 租赁车辆
+     */
+    private String zuLin;
+    /**
+     * 合计
+     */
+    private String total;
+    /**
+     * 成新率
+     */
+    private String chengXinLv;
+
+    public CarCqclqkVo(String num, String firstUnit) {
+        this.num = num;
+        this.firstUnit = firstUnit;
+        this.ziYou = "";
+        this.lte6 = "";
+        this.gte6lte10 = "";
+        this.gt10 = "";
+        this.zuLin = "";
+        this.total = "";
+        this.chengXinLv = "";
+    }
+
+    public CarCqclqkVo(Integer num, String firstUnit) {
+        this.num = String.valueOf(num);
+        this.firstUnit = firstUnit;
+        this.ziYou = "0";
+        this.lte6 = "0";
+        this.gte6lte10 = "0";
+        this.gt10 = "0";
+        this.zuLin = "0";
+        this.total = "0";
+        this.chengXinLv = "0%";
+    }
+
+    public void update(CarCqclqkPo carCqclqkPo) {
+        DecimalFormat integerFormat = new DecimalFormat("#,###");
+        DecimalFormat percentFormat = new DecimalFormat("0%");
+        this.ziYou = integerFormat.format(carCqclqkPo.getZiYou());
+        this.lte6 = integerFormat.format(carCqclqkPo.getLte6());
+        this.gte6lte10 = integerFormat.format(carCqclqkPo.getGte6lte10());
+        this.gt10 = integerFormat.format(carCqclqkPo.getGt10());
+        this.zuLin = integerFormat.format(carCqclqkPo.getZuLin());
+        this.total = integerFormat.format(carCqclqkPo.getTotal());
+        this.chengXinLv = percentFormat.format(carCqclqkPo.getChengXinLv());
+    }
+}

+ 84 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarDxUnitVo.java

@@ -0,0 +1,84 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarDxUnitPo;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.text.DecimalFormat;
+
+@NoArgsConstructor
+@Data
+public class CarDxUnitVo {
+    /**
+     * 序号
+     */
+    private String num;
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 去年车数
+     */
+    private String totalLy;
+    /**
+     * 去年低效车数
+     */
+    private String diXiaoCountLy;
+    /**
+     * 去年低效占比
+     */
+    private String diXiaoPercentLy;
+    /**
+     * 今年车数
+     */
+    private String totalTy;
+    /**
+     * 今年低效车数
+     */
+    private String diXiaoCountTy;
+    /**
+     * 今年低效占比
+     */
+    private String diXiaoPercentTy;
+    /**
+     * 低效占比变化
+     */
+    private String diXiaoChange;
+
+    public CarDxUnitVo(String num, String firstUnit) {
+        this.num = num;
+        this.firstUnit = firstUnit;
+        this.totalLy = "";
+        this.diXiaoCountLy = "";
+        this.diXiaoPercentLy = "";
+        this.totalTy = "";
+        this.diXiaoCountTy = "";
+        this.diXiaoPercentTy = "";
+        this.diXiaoChange = "";
+    }
+
+    public CarDxUnitVo(Integer num, String firstUnit) {
+        this.num = String.valueOf(num);
+        this.firstUnit = firstUnit;
+        this.totalLy = "0";
+        this.diXiaoCountLy = "0";
+        this.diXiaoPercentLy = "0.0%";
+        this.totalTy = "0";
+        this.diXiaoCountTy = "0";
+        this.diXiaoPercentTy = "0.0%";
+        this.diXiaoChange = "0.0%";
+    }
+
+    public void update(CarDxUnitPo carDxUnitPo) {
+        DecimalFormat integerFormat = new DecimalFormat("#,###");
+        DecimalFormat percentFormat = new DecimalFormat("0.0%");
+        this.totalLy = integerFormat.format(carDxUnitPo.getTotalLy());
+        this.diXiaoCountLy = integerFormat.format(carDxUnitPo.getDiXiaoCountLy());
+        this.diXiaoPercentLy = percentFormat.format(carDxUnitPo.getDiXiaoPercentLy());
+        this.totalTy = integerFormat.format(carDxUnitPo.getTotalTy());
+        this.diXiaoCountTy = integerFormat.format(carDxUnitPo.getDiXiaoCountTy());
+        this.diXiaoPercentTy = percentFormat.format(carDxUnitPo.getDiXiaoPercentTy());
+        this.diXiaoChange = percentFormat.format(carDxUnitPo.getDiXiaoChange());
+    }
+}

+ 65 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarJygxUnitVo.java

@@ -0,0 +1,65 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarJygxUnitPo;
+import lombok.Data;
+
+import java.text.DecimalFormat;
+
+@Data
+public class CarJygxUnitVo {
+    /**
+     * 单位
+     */
+    private String firstUnit;
+    /**
+     * 轿车
+     */
+    private String jc;
+    /**
+     * 皮卡车
+     */
+    private String pkc;
+    /**
+     * 商务车
+     */
+    private String swc;
+    /**
+     * 特种车
+     */
+    private String tzc;
+    /**
+     * 越野车
+     */
+    private String yyc;
+    /**
+     * 中型面包车(8-20座的面包车)
+     */
+    private String zxmbc;
+    /**
+     * 总计
+     */
+    private String total;
+
+    public CarJygxUnitVo() {
+        this.firstUnit = "";
+        this.jc = "";
+        this.pkc = "";
+        this.swc = "";
+        this.tzc = "";
+        this.yyc = "";
+        this.zxmbc = "";
+        this.total = "";
+    }
+
+    public CarJygxUnitVo(CarJygxUnitPo po) {
+        DecimalFormat integerFormat = new DecimalFormat("#,###");
+        this.firstUnit = po.getFirstUnit();
+        this.jc = integerFormat.format(po.getJc());
+        this.pkc = integerFormat.format(po.getPkc());
+        this.swc = integerFormat.format(po.getSwc());
+        this.tzc = integerFormat.format(po.getTzc());
+        this.yyc = integerFormat.format(po.getYyc());
+        this.zxmbc = integerFormat.format(po.getZxmbc());
+        this.total = integerFormat.format(po.getTotal());
+    }
+}

+ 65 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarReportVo.java

@@ -0,0 +1,65 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import lombok.Data;
+
+@Data
+public class CarReportVo {
+    public static final String PLACEHOLDER = "X";
+    private Integer endYearMonth;
+    /**
+     * 上个报告年
+     */
+    private String lastReportYear;
+    /**
+     * 报告年
+     */
+    private String reportYear;
+    /**
+     * 报告月
+     */
+    private String reportMonth;
+    /**
+     * 当前年
+     */
+    private String currentYear;
+    /**
+     * 当前月
+     */
+    private String currentMonth;
+    /**
+     * logo图片
+     */
+    private String logoImg;
+    /**
+     * 车辆概况
+     */
+    private CarClgkVo clgk;
+    /**
+     * 车辆费用
+     */
+    private CarClfyVo clfy;
+    /**
+     * 异常燃油费
+     */
+    private CarYcryfVo ycryf;
+    /**
+     * 自有车辆异常维修费
+     */
+    private CarZyycwxVo zyycwx;
+    /**
+     * 租赁车辆异常维修费
+     */
+    private CarZlycwxVo zlycwx;
+    /**
+     * 车辆低效
+     */
+    private CarCldxVo cldx;
+    /**
+     * 违规用车
+     */
+    private CarWgycVo wgyc;
+    /**
+     * 违章处理异常
+     */
+    private CarWzclycVo wzclyc;
+}

+ 21 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarRyycUnitVo.java

@@ -0,0 +1,21 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarRyycUnitPo;
+import lombok.Data;
+
+@Data
+public class CarRyycUnitVo {
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 车数
+     */
+    private String total;
+
+    public CarRyycUnitVo(CarRyycUnitPo carRyycUnitPo) {
+        this.firstUnit = carRyycUnitPo.getFirstUnit();
+        this.total = carRyycUnitPo.getTotal().toString();
+    }
+}

+ 82 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarSnfyVo.java

@@ -0,0 +1,82 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarSnfyPo;
+import lombok.Data;
+
+import java.text.DecimalFormat;
+
+@Data
+public class CarSnfyVo {
+    /**
+     * 序号
+     */
+    private String num;
+    /**
+     * 单位
+     */
+    private String firstUnit;
+    /**
+     * 本年
+     */
+    private String tyFy;
+    /**
+     * 上年
+     */
+    private String lyFy;
+    /**
+     * 预算累计
+     */
+    private String budgetLj;
+    /**
+     * 同比增减
+     */
+    private String tbzj;
+    /**
+     * 同比百分比
+     */
+    private String tbbfb;
+    /**
+     * 预算偏差
+     */
+    private String yspc;
+    /**
+     * 偏差百分比
+     */
+    private String yspcbfb;
+
+    public CarSnfyVo(String num, String firstUnit) {
+        this.num = num;
+        this.firstUnit = firstUnit;
+        this.tyFy = "";
+        this.lyFy = "";
+        this.budgetLj = "";
+        this.tbzj = "";
+        this.tbbfb = "";
+        this.yspc = "";
+        this.yspcbfb = "";
+    }
+
+    public CarSnfyVo(Integer num, String firstUnit) {
+        this.num = String.valueOf(num);
+        this.firstUnit = firstUnit;
+        this.tyFy = "0.00";
+        this.lyFy = "0.00";
+        this.budgetLj = "0.00";
+        this.tbzj = "0.00";
+        this.tbbfb = "0.00%";
+        this.yspc = "0.00";
+        this.yspcbfb = "0.00%";
+    }
+
+    public void update(CarSnfyPo carSnfyPo) {
+        DecimalFormat numberFormat = new DecimalFormat("#,##0.00");
+        DecimalFormat percentFormat = new DecimalFormat("0.00%");
+        this.tyFy = numberFormat.format(carSnfyPo.getTyFy());
+        this.lyFy = numberFormat.format(carSnfyPo.getLyFy());
+        this.budgetLj = numberFormat.format(carSnfyPo.getBudgetLj());
+        this.tbzj =  numberFormat.format(carSnfyPo.getTbzj());
+        this.tbbfb = carSnfyPo.getTbbfb() == null ? "" : percentFormat.format(carSnfyPo.getTbbfb());
+        this.yspc = numberFormat.format(carSnfyPo.getYspc());
+        this.yspcbfb = carSnfyPo.getYspcbfb() == null ? "" : percentFormat.format(carSnfyPo.getYspcbfb());
+    }
+}

+ 23 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWgUnitVo.java

@@ -0,0 +1,23 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@Data
+public class CarWgUnitVo {
+    private String firstUnit;
+    private String m1;
+    private String m2;
+    private String m3;
+    private String m4;
+    private String m5;
+    private String m6;
+    private String m7;
+    private String m8;
+    private String m9;
+    private String m10;
+    private String m11;
+    private String m12;
+    private String total;
+}

+ 149 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWgycVo.java

@@ -0,0 +1,149 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.config.CarReportConfig;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWgPo;
+import lombok.Data;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Stream;
+
+@Data
+public class CarWgycVo {
+    /**
+     * 全省车辆违规行驶累计次数
+     */
+    private String qswg;
+    /**
+     * 违规车辆次数最多单位
+     */
+    private String wgzddw;
+    /**
+     * 违规最多次数
+     */
+    private String wgzdcs;
+    /**
+     * 违规用车一级单位统计
+     */
+    private List<CarWgUnitVo> wgUnitList;
+
+    public CarWgycVo(List<CarWgUnitVo> wgUnitList, List<CarWgPo> wgList, CarReportConfig carReportConfig) throws IOException {
+        this.wgUnitList = wgUnitList;
+        wgUnitList.stream().filter(t -> t.getFirstUnit().equals("合计")).findFirst()
+                .ifPresent(t -> this.qswg = t.getTotal());
+        wgUnitList.stream().filter(t -> !t.getFirstUnit().equals("合计"))
+                .max(Comparator.comparingInt(t -> Integer.parseInt(t.getTotal()))).ifPresent(t -> {
+            this.wgzddw = t.getFirstUnit();
+            this.wgzdcs = t.getTotal();
+        });
+        writeWgXlsx(wgList, carReportConfig);
+    }
+
+    /**
+     * 违规用车明细xlsx
+     */
+    private void writeWgXlsx(List<CarWgPo> wgList, CarReportConfig carReportConfig) throws IOException {
+        try (SXSSFWorkbook wb = new SXSSFWorkbook();
+//             FastByteArrayOutputStream os = new FastByteArrayOutputStream()
+             OutputStream os = Files.newOutputStream(Paths.get(carReportConfig.getWgXlsx()))
+        ) {
+            DataFormat dataFormat = wb.createDataFormat();
+            // 日期时间样式
+            CellStyle dateTimeCellStyle = wb.createCellStyle();
+            dateTimeCellStyle.setDataFormat(dataFormat.getFormat("yyyy/MM/dd HH:mm:ss"));
+            // 表头样式
+            CellStyle headerCellStyle = wb.createCellStyle();
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            SXSSFSheet sheet = wb.createSheet();
+            AtomicInteger rowIndex = new AtomicInteger(0);
+            // 表头
+            Row headerRow = sheet.createRow(rowIndex.getAndIncrement());
+            List<String> headers = Stream.of("车辆所属单位", "车牌号码", "车辆类型", "车辆使用性质", "报警区域描述",
+                    "报警规则描述", "越界时间", "是否执行中越界", "单位", "二级", "三级").toList();
+            int headerSize = headers.size();
+            for (int i = 0; i < headerSize; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers.get(i));
+                cell.setCellStyle(headerCellStyle);
+                // 根据内容长度设置列宽
+                int columnWidth = headers.get(i).length() * 256 * 2 + 256 * 10;
+                sheet.setColumnWidth(i, columnWidth);
+            }
+            for (CarWgPo t : wgList) {
+                AtomicInteger columnIndex = new AtomicInteger(0);
+                Row row = sheet.createRow(rowIndex.getAndIncrement());
+                // 车辆所属单位
+                Cell cheLiangSuoShuDanWeiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangSuoShuDanWei() != null) {
+                    cheLiangSuoShuDanWeiCell.setCellValue(t.getCheLiangSuoShuDanWei());
+                }
+                // 车牌号
+                Cell chePaiHaoCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChePaiHao() != null) {
+                    chePaiHaoCell.setCellValue(t.getChePaiHao());
+                }
+                // 车辆类型
+                Cell cheLiangLeiXingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLeiXing() != null) {
+                    cheLiangLeiXingCell.setCellValue(t.getCheLiangLeiXing());
+                }
+                // 车辆使用性质
+                Cell cheLiangShiYongXingZhiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangShiYongXingZhi() != null) {
+                    cheLiangShiYongXingZhiCell.setCellValue(t.getCheLiangShiYongXingZhi());
+                }
+                // 报警区域描述
+                Cell baoJingQuYuMiaoShuCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getBaoJingQuYuMiaoShu() != null) {
+                    baoJingQuYuMiaoShuCell.setCellValue(t.getBaoJingQuYuMiaoShu());
+                }
+                // 报警规则描述
+                Cell baoJingGuiZeMiaoShuCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getBaoJingGuiZeMiaoShu() != null) {
+                    baoJingGuiZeMiaoShuCell.setCellValue(t.getBaoJingGuiZeMiaoShu());
+                }
+                // 越界时间
+                Cell yueJieShiJianCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getYueJieShiJian() != null) {
+                    yueJieShiJianCell.setCellValue(t.getYueJieShiJian());
+                }
+                yueJieShiJianCell.setCellStyle(dateTimeCellStyle);
+                // 是否执行中越界
+                Cell shiFouZhiXingZhongYueJieCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getShiFouZhiXingZhongYueJie() != null) {
+                    shiFouZhiXingZhongYueJieCell.setCellValue(t.getShiFouZhiXingZhongYueJie());
+                }
+                // 单位
+                Cell firstUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getFirstUnit() != null) {
+                    firstUnitCell.setCellValue(t.getFirstUnit());
+                }
+                // 二级
+                Cell secondUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getSecondUnit() != null) {
+                    secondUnitCell.setCellValue(t.getSecondUnit());
+                }
+                // 三级
+                Cell thirdUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getThirdUnit() != null) {
+                    thirdUnitCell.setCellValue(t.getThirdUnit());
+                }
+            }
+            wb.write(os);
+        }
+    }
+}

+ 18 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWxQsVo.java

@@ -0,0 +1,18 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxQsPo;
+import lombok.Data;
+
+@Data
+public class CarWxQsVo {
+    private String idx;
+    /**
+     * 维修
+     */
+    private String val;
+
+    public CarWxQsVo(CarWxQsPo carWxQsPo) {
+        this.idx = String.valueOf(carWxQsPo.getMonthNo() - 1);
+        this.val = carWxQsPo.getTmWx().toString();
+    }
+}

+ 23 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWxUnitVo.java

@@ -0,0 +1,23 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarWxUnitPo;
+import lombok.Data;
+
+@Data
+public class CarWxUnitVo {
+    private String idx;
+    /**
+     * 二级组织机构
+     */
+    private String cat;
+    /**
+     * 自有车辆单车维修
+     */
+    private String val;
+
+    public CarWxUnitVo(String idx, CarWxUnitPo carWxUnitPo) {
+        this.idx = idx;
+        this.cat = carWxUnitPo.getAreaName();
+        this.val = carWxUnitPo.getTyWxAvg().toString();
+    }
+}

+ 21 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWzUnitVo.java

@@ -0,0 +1,21 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarWzUnitPo;
+import lombok.Data;
+
+@Data
+public class CarWzUnitVo {
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 违章次数
+     */
+    private String total;
+
+    public CarWzUnitVo(CarWzUnitPo carWzUnitPo) {
+        this.firstUnit = carWzUnitPo.getFirstUnit();
+        this.total = String.valueOf(carWzUnitPo.getTotal());
+    }
+}

+ 145 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarWzclycVo.java

@@ -0,0 +1,145 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.config.CarReportConfig;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWzPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarWzUnitPo;
+import lombok.Data;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Stream;
+
+@Data
+public class CarWzclycVo {
+    /**
+     * 违章长期未处理一级单位统计
+     */
+    private List<CarWzUnitVo> wzUnitList;
+
+    public CarWzclycVo(List<CarWzUnitPo> wzUnitList, List<CarWzPo> wzList, CarReportConfig carReportConfig) throws IOException {
+        this.wzUnitList = new ArrayList<>();
+        for (CarWzUnitPo carWzUnitPo : wzUnitList) {
+            this.wzUnitList.add(new CarWzUnitVo(carWzUnitPo));
+        }
+        writeWzXlsx(wzList, carReportConfig);
+    }
+
+    /**
+     * 违章长期未处理xlsx
+     */
+    private void writeWzXlsx(List<CarWzPo> wzList, CarReportConfig carReportConfig) throws IOException {
+        try (SXSSFWorkbook wb = new SXSSFWorkbook();
+//             FastByteArrayOutputStream os = new FastByteArrayOutputStream()
+             OutputStream os = Files.newOutputStream(Paths.get(carReportConfig.getWzXlsx()))
+        ) {
+            DataFormat dataFormat = wb.createDataFormat();
+            // 数字样式
+            CellStyle numberCellStyle = wb.createCellStyle();
+            numberCellStyle.setDataFormat(dataFormat.getFormat("#,##0.00"));
+            numberCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 整数样式
+            CellStyle integerCellStyle = wb.createCellStyle();
+            integerCellStyle.setDataFormat(dataFormat.getFormat("#,##0"));
+            integerCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 日期时间样式
+            CellStyle dateTimeCellStyle = wb.createCellStyle();
+            dateTimeCellStyle.setDataFormat(dataFormat.getFormat("yyyy/MM/dd HH:mm:ss"));
+            // 表头样式
+            CellStyle headerCellStyle = wb.createCellStyle();
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            SXSSFSheet sheet = wb.createSheet();
+            AtomicInteger rowIndex = new AtomicInteger(0);
+            // 表头
+            Row headerRow = sheet.createRow(rowIndex.getAndIncrement());
+            List<String> headers = Stream.of("车牌号", "单位", "二级", "三级", "违章时间", "违章地点", "违章详情",
+                    "扣分", "罚款", "违章未处理时长(天)", "线下实际处理状态(最终状态)").toList();
+            int headerSize = headers.size();
+            for (int i = 0; i < headerSize; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers.get(i));
+                cell.setCellStyle(headerCellStyle);
+                // 根据内容长度设置列宽
+                int columnWidth = headers.get(i).length() * 256 * 2 + 256 * 10;
+                sheet.setColumnWidth(i, columnWidth);
+            }
+            for (CarWzPo t : wzList) {
+                AtomicInteger columnIndex = new AtomicInteger(0);
+                Row row = sheet.createRow(rowIndex.getAndIncrement());
+                // 车牌号
+                Cell chePaiHaoCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChePaiHao() != null) {
+                    chePaiHaoCell.setCellValue(t.getChePaiHao());
+                }
+                // 单位
+                Cell firstUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getFirstUnit() != null) {
+                    firstUnitCell.setCellValue(t.getFirstUnit());
+                }
+                // 二级
+                Cell secondUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getSecondUnit() != null) {
+                    secondUnitCell.setCellValue(t.getSecondUnit());
+                }
+                // 三级
+                Cell thirdUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getThirdUnit() != null) {
+                    thirdUnitCell.setCellValue(t.getThirdUnit());
+                }
+                // 违章时间
+                Cell weiZhangShiJianCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWeiZhangShiJian() != null) {
+                    weiZhangShiJianCell.setCellValue(t.getWeiZhangShiJian());
+                }
+                weiZhangShiJianCell.setCellStyle(dateTimeCellStyle);
+                // 违章地点
+                Cell weiZhangDiDianCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWeiZhangDiDian() != null) {
+                    weiZhangDiDianCell.setCellValue(t.getWeiZhangDiDian());
+                }
+                // 违章详情
+                Cell weiZhangXiangQingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWeiZhangXiangQing() != null) {
+                    weiZhangXiangQingCell.setCellValue(t.getWeiZhangXiangQing());
+                }
+                // 扣分
+                Cell kouFenCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getKouFen() != null) {
+                    kouFenCell.setCellValue(t.getKouFen());
+                }
+                kouFenCell.setCellStyle(integerCellStyle);
+                // 罚款
+                Cell faKuanCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getFaKuan() != null) {
+                    faKuanCell.setCellValue(t.getFaKuan().doubleValue());
+                }
+                faKuanCell.setCellStyle(integerCellStyle);
+                // 违章未处理时长
+                Cell weiZhangWeiChuLiShiChangCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWeiZhangWeiChuLiShiChang() != null) {
+                    weiZhangWeiChuLiShiChangCell.setCellValue(t.getWeiZhangWeiChuLiShiChang());
+                }
+                weiZhangWeiChuLiShiChangCell.setCellStyle(integerCellStyle);
+                // 线下实际处理状态
+                Cell chuLiZhuangTaiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChuLiZhuangTai() != null) {
+                    chuLiZhuangTaiCell.setCellValue(t.getChuLiZhuangTai());
+                }
+            }
+            wb.write(os);
+        }
+    }
+}

+ 149 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarYcryfVo.java

@@ -0,0 +1,149 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.config.CarReportConfig;
+import com.nokia.finance.tasks.pojo.po.car_report.CarRyycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarRyycUnitPo;
+import lombok.Data;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Stream;
+
+@Data
+public class CarYcryfVo {
+    /**
+     * 燃油异常一级单位统计
+     */
+    private List<CarRyycUnitVo> ryycUnitList;
+
+    public CarYcryfVo(List<CarRyycUnitPo> ryycUnitList, List<CarRyycPo> carRyycPoList, CarReportConfig carReportConfig)
+            throws IOException {
+        this.ryycUnitList = new ArrayList<>();
+        for (CarRyycUnitPo carRyycUnitPo : ryycUnitList) {
+            this.ryycUnitList.add(new CarRyycUnitVo(carRyycUnitPo));
+        }
+        writeRyycXlsx(carRyycPoList, carReportConfig);
+    }
+
+    /**
+     * 燃油异常xlsx
+     */
+    private void writeRyycXlsx(List<CarRyycPo> carRyycPoList, CarReportConfig carReportConfig) throws IOException {
+        try (SXSSFWorkbook wb = new SXSSFWorkbook();
+//             FastByteArrayOutputStream os = new FastByteArrayOutputStream()
+             OutputStream os = Files.newOutputStream(Paths.get(carReportConfig.getRyycXlsx()))
+        ) {
+            DataFormat dataFormat = wb.createDataFormat();
+            // 数字样式
+            CellStyle numberCellStyle = wb.createCellStyle();
+            numberCellStyle.setDataFormat(dataFormat.getFormat("#,##0.00"));
+            numberCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 表头样式
+            CellStyle headerCellStyle = wb.createCellStyle();
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            SXSSFSheet sheet = wb.createSheet();
+            AtomicInteger rowIndex = new AtomicInteger(0);
+            // 表头
+            Row headerRow = sheet.createRow(rowIndex.getAndIncrement());
+            List<String> headers = Stream.of("车牌号", "单位", "二级", "三级", "车辆所属单位", "车辆来源", "车辆类型",
+                    "车辆使用性质", "燃油", "里程", "百公里油费", "百公里油耗", "排名").toList();
+            int headerSize = headers.size();
+            for (int i = 0; i < headerSize; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers.get(i));
+                cell.setCellStyle(headerCellStyle);
+                // 根据内容长度设置列宽
+                int columnWidth = headers.get(i).length() * 256 * 2 + 256 * 5;
+                sheet.setColumnWidth(i, columnWidth);
+            }
+            for (CarRyycPo t : carRyycPoList) {
+                AtomicInteger columnIndex = new AtomicInteger(0);
+                Row row = sheet.createRow(rowIndex.getAndIncrement());
+                // 车牌号
+                Cell chePaiHaoCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChePaiHao() != null) {
+                    chePaiHaoCell.setCellValue(t.getChePaiHao());
+                }
+                // 单位
+                Cell firstUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getFirstUnit() != null) {
+                    firstUnitCell.setCellValue(t.getFirstUnit());
+                }
+                // 二级
+                Cell secondUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getSecondUnit() != null) {
+                    secondUnitCell.setCellValue(t.getSecondUnit());
+                }
+                // 三级
+                Cell thirdUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getThirdUnit() != null) {
+                    thirdUnitCell.setCellValue(t.getThirdUnit());
+                }
+                // 车辆所属单位
+                Cell cheLiangSuoShuDanWeiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangSuoShuDanWei() != null) {
+                    cheLiangSuoShuDanWeiCell.setCellValue(t.getCheLiangSuoShuDanWei());
+                }
+                // 车辆来源
+                Cell cheLiangLaiYuanCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLaiYuan() != null) {
+                    cheLiangLaiYuanCell.setCellValue(t.getCheLiangLaiYuan());
+                }
+                // 车辆类型
+                Cell cheLiangLeiXingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLeiXing() != null) {
+                    cheLiangLeiXingCell.setCellValue(t.getCheLiangLeiXing());
+                }
+                // 车辆使用性质
+                Cell cheLiangShiYongXingZhiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangShiYongXingZhi() != null) {
+                    cheLiangShiYongXingZhiCell.setCellValue(t.getCheLiangShiYongXingZhi());
+                }
+                // 燃油
+                Cell ranYouSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getRanYouSum() != null) {
+                    ranYouSumCell.setCellValue(t.getRanYouSum().doubleValue());
+                }
+                ranYouSumCell.setCellStyle(numberCellStyle);
+                // 里程
+                Cell zongLiChengSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getZongLiChengSum() != null) {
+                    zongLiChengSumCell.setCellValue(t.getZongLiChengSum().doubleValue());
+                }
+                zongLiChengSumCell.setCellStyle(numberCellStyle);
+                // 百公里油费
+                Cell baiGongLiYouFeiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getBaiGongLiYouFei() != null) {
+                    baiGongLiYouFeiCell.setCellValue(t.getBaiGongLiYouFei().doubleValue());
+                }
+                baiGongLiYouFeiCell.setCellStyle(numberCellStyle);
+                // 百公里油耗
+                Cell baiGongLiYouHaoCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getBaiGongLiYouHao() != null) {
+                    baiGongLiYouHaoCell.setCellValue(t.getBaiGongLiYouHao().doubleValue());
+                }
+                baiGongLiYouHaoCell.setCellStyle(numberCellStyle);
+                // 排名
+                Cell baiGongLiYouFeiRankCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getBaiGongLiYouFeiRank() != null) {
+                    baiGongLiYouFeiRankCell.setCellValue(t.getBaiGongLiYouFeiRank().doubleValue());
+                }
+            }
+            wb.write(os);
+        }
+    }
+}

+ 93 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZlwxycVo.java

@@ -0,0 +1,93 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarZlwxycPo;
+import lombok.Data;
+
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.time.format.DateTimeFormatter;
+
+@Data
+public class CarZlwxycVo {
+    /**
+     * 车牌号
+     */
+    private String chePaiHao;
+    /**
+     * 一级
+     */
+    private String firstUnit;
+    /**
+     * 二级
+     */
+    private String secondUnit;
+    /**
+     * 三级
+     */
+    private String thirdUnit;
+    /**
+     * 车辆所属单位
+     */
+    private String cheLiangSuoShuDanWei;
+    /**
+     * 累计维修
+     */
+    private String weiXiuSum;
+    /**
+     * 排名
+     */
+    private String weiXiuRank;
+    /**
+     * 车龄
+     */
+    private String cheLing;
+    /**
+     * 登记日期
+     */
+    private String dengJiRiQi;
+    /**
+     * 车辆来源
+     */
+    private String cheLiangLaiYuan;
+    /**
+     * 车辆类型
+     */
+    private String cheLiangLeiXing;
+    /**
+     * 车辆使用性质
+     */
+    private String cheLiangShiYongXingZhi;
+
+    public CarZlwxycVo() {
+        this.chePaiHao = "";
+        this.firstUnit = "";
+        this.secondUnit = "";
+        this.thirdUnit = "";
+        this.cheLiangSuoShuDanWei = "";
+        this.weiXiuSum = "";
+        this.weiXiuRank = "";
+        this.dengJiRiQi = "";
+        this.cheLing = "";
+        this.cheLiangLaiYuan = "";
+        this.cheLiangLeiXing = "";
+        this.cheLiangShiYongXingZhi = "";
+    }
+
+    public CarZlwxycVo(CarZlwxycPo carZlwxycPo) {
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
+        DecimalFormat numberFormat = new DecimalFormat("#,##0.00");
+        DecimalFormat integerFormat = new DecimalFormat("#,###");
+        this.chePaiHao = carZlwxycPo.getChePaiHao();
+        this.firstUnit = carZlwxycPo.getFirstUnit();
+        this.secondUnit = carZlwxycPo.getSecondUnit();
+        this.thirdUnit = carZlwxycPo.getThirdUnit();
+        this.cheLiangSuoShuDanWei = carZlwxycPo.getCheLiangSuoShuDanWei();
+        this.weiXiuSum = numberFormat.format(carZlwxycPo.getWeiXiuSum());
+        this.weiXiuRank = integerFormat.format(carZlwxycPo.getWeiXiuRank());
+        this.dengJiRiQi = dateTimeFormatter.format(carZlwxycPo.getDengJiRiQi());
+        this.cheLing = integerFormat.format(carZlwxycPo.getCheLing().setScale(0, RoundingMode.CEILING));
+        this.cheLiangLaiYuan = carZlwxycPo.getCheLiangLaiYuan();
+        this.cheLiangLeiXing = carZlwxycPo.getCheLiangLeiXing();
+        this.cheLiangShiYongXingZhi = carZlwxycPo.getCheLiangShiYongXingZhi();
+    }
+}

+ 35 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZlycwxVo.java

@@ -0,0 +1,35 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarZlwxycPo;
+import lombok.Data;
+import org.springframework.util.CollectionUtils;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class CarZlycwxVo {
+    /**
+     * 租赁车辆维修费异常个数
+     */
+    private String total;
+    /**
+     * 租赁车辆维修费异常
+     */
+    private List<CarZlwxycVo> zlwxycList;
+
+    public CarZlycwxVo(List<CarZlwxycPo> zlwxycList) {
+        this.zlwxycList = new ArrayList<>();
+        if (CollectionUtils.isEmpty(zlwxycList)) {
+            this.total = "0";
+            this.zlwxycList.add(new CarZlwxycVo());
+        } else {
+            DecimalFormat integerFormat = new DecimalFormat("#,###");
+            for (CarZlwxycPo carZlwxycPo : zlwxycList) {
+                this.zlwxycList.add(new CarZlwxycVo(carZlwxycPo));
+            }
+            this.total = integerFormat.format(this.zlwxycList.size());
+        }
+    }
+}

+ 21 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZywxycUnitVo.java

@@ -0,0 +1,21 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.pojo.po.car_report.CarZywxycUnitPo;
+import lombok.Data;
+
+@Data
+public class CarZywxycUnitVo {
+    /**
+     * 一级单位
+     */
+    private String firstUnit;
+    /**
+     * 车数
+     */
+    private String total;
+
+    public CarZywxycUnitVo(CarZywxycUnitPo carZywxycUnitPo) {
+        this.firstUnit = carZywxycUnitPo.getFirstUnit();
+        this.total = carZywxycUnitPo.getTotal().toString();
+    }
+}

+ 147 - 0
src/main/java/com/nokia/finance/tasks/pojo/vo/car_report/CarZyycwxVo.java

@@ -0,0 +1,147 @@
+package com.nokia.finance.tasks.pojo.vo.car_report;
+
+import com.nokia.finance.tasks.config.CarReportConfig;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZywxycPo;
+import com.nokia.finance.tasks.pojo.po.car_report.CarZywxycUnitPo;
+import lombok.Data;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.RoundingMode;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Stream;
+
+@Data
+public class CarZyycwxVo {
+    /**
+     * 自有车辆异常维修费一级单位统计
+     */
+    private List<CarZywxycUnitVo> zywxycUnitList;
+
+    public CarZyycwxVo(List<CarZywxycUnitPo> zywxycUnitList, List<CarZywxycPo> carZywxycPoList,
+                       CarReportConfig carReportConfig) throws IOException {
+        this.zywxycUnitList = new ArrayList<>();
+        for (CarZywxycUnitPo carZywxycUnitPo : zywxycUnitList) {
+            this.zywxycUnitList.add(new CarZywxycUnitVo(carZywxycUnitPo));
+        }
+        writeZywxycXlsx(carZywxycPoList, carReportConfig);
+    }
+
+    /**
+     * 自有车辆异常维修费xlsx
+     */
+    private void writeZywxycXlsx(List<CarZywxycPo> carZywxycPoList, CarReportConfig carReportConfig) throws IOException {
+        try (SXSSFWorkbook wb = new SXSSFWorkbook();
+//             FastByteArrayOutputStream os = new FastByteArrayOutputStream()
+             OutputStream os = Files.newOutputStream(Paths.get(carReportConfig.getZywxycXlsx()))
+        ) {
+            DataFormat dataFormat = wb.createDataFormat();
+            // 数字样式
+            CellStyle numberCellStyle = wb.createCellStyle();
+            numberCellStyle.setDataFormat(dataFormat.getFormat("#,##0.00"));
+            numberCellStyle.setAlignment(HorizontalAlignment.RIGHT);
+            // 日期样式
+            CellStyle dateCellStyle = wb.createCellStyle();
+            dateCellStyle.setDataFormat(dataFormat.getFormat("yyyy/MM/dd"));
+            dateCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            // 表头样式
+            CellStyle headerCellStyle = wb.createCellStyle();
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            SXSSFSheet sheet = wb.createSheet();
+            AtomicInteger rowIndex = new AtomicInteger(0);
+            // 表头
+            Row headerRow = sheet.createRow(rowIndex.getAndIncrement());
+            List<String> headers = Stream.of("车牌号", "单位", "二级", "三级", "车辆所属单位", "累计维修", "排名",
+                    "车龄", "登记日期", "车辆来源", "车辆类型", "车辆使用性质").toList();
+            int headerSize = headers.size();
+            for (int i = 0; i < headerSize; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers.get(i));
+                cell.setCellStyle(headerCellStyle);
+                // 根据内容长度设置列宽
+                int columnWidth = headers.get(i).length() * 256 * 2 + 256 * 5;
+                sheet.setColumnWidth(i, columnWidth);
+            }
+            for (CarZywxycPo t : carZywxycPoList) {
+                AtomicInteger columnIndex = new AtomicInteger(0);
+                Row row = sheet.createRow(rowIndex.getAndIncrement());
+                // 车牌号
+                Cell chePaiHaoCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getChePaiHao() != null) {
+                    chePaiHaoCell.setCellValue(t.getChePaiHao());
+                }
+                // 单位
+                Cell firstUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getFirstUnit() != null) {
+                    firstUnitCell.setCellValue(t.getFirstUnit());
+                }
+                // 二级
+                Cell secondUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getSecondUnit() != null) {
+                    secondUnitCell.setCellValue(t.getSecondUnit());
+                }
+                // 三级
+                Cell thirdUnitCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getThirdUnit() != null) {
+                    thirdUnitCell.setCellValue(t.getThirdUnit());
+                }
+                // 车辆所属单位
+                Cell cheLiangSuoShuDanWeiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangSuoShuDanWei() != null) {
+                    cheLiangSuoShuDanWeiCell.setCellValue(t.getCheLiangSuoShuDanWei());
+                }
+                // 累计维修
+                Cell weiXiuSumCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWeiXiuSum() != null) {
+                    weiXiuSumCell.setCellValue(t.getWeiXiuSum().doubleValue());
+                }
+                weiXiuSumCell.setCellStyle(numberCellStyle);
+                // 排名
+                Cell weiXiuRankCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getWeiXiuRank() != null) {
+                    weiXiuRankCell.setCellValue(t.getWeiXiuRank());
+                }
+                // 车龄
+                Cell cheLingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLing() != null) {
+                    cheLingCell.setCellValue(t.getCheLing().setScale(0, RoundingMode.CEILING).intValue());
+                }
+                // 登记日期
+                Cell dengJiRiQiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getDengJiRiQi() != null) {
+                    dengJiRiQiCell.setCellValue(t.getDengJiRiQi());
+                }
+                dengJiRiQiCell.setCellStyle(dateCellStyle);
+                // 车辆来源
+                Cell cheLiangLaiYuanCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLaiYuan() != null) {
+                    cheLiangLaiYuanCell.setCellValue(t.getCheLiangLaiYuan());
+                }
+                // 车辆类型
+                Cell cheLiangLeiXingCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangLeiXing() != null) {
+                    cheLiangLeiXingCell.setCellValue(t.getCheLiangLeiXing());
+                }
+                // 车辆使用性质
+                Cell cheLiangShiYongXingZhiCell = row.createCell(columnIndex.getAndIncrement());
+                if (t.getCheLiangShiYongXingZhi() != null) {
+                    cheLiangShiYongXingZhiCell.setCellValue(t.getCheLiangShiYongXingZhi());
+                }
+            }
+            wb.write(os);
+        }
+    }
+}

+ 5 - 1
src/main/java/com/nokia/finance/tasks/service/JobService.java

@@ -1,6 +1,7 @@
 package com.nokia.finance.tasks.service;
 
 import com.nokia.finance.tasks.common.R;
+import com.nokia.finance.tasks.jobs.car.CarReportJob;
 import com.nokia.finance.tasks.jobs.car.chengben.CarBaoXianJob;
 import com.nokia.finance.tasks.jobs.car.chengben.CarDaWeiXiuJob;
 import com.nokia.finance.tasks.jobs.car.chengben.CarLuQiaoJob;
@@ -44,6 +45,7 @@ public class JobService {
     private final CarLiChengDayJob carLiChengDayJob;
     private final CarSiCheGongYongJob carSiCheGongYongJob;
     private final HouseRentInRepairMonthJob houseRentInRepairMonthJob;
+    private final CarReportJob carReportJob;
 
     public JobService(CarBaseDataDayJob carBaseDataDayJob, CarYueJieJob carYueJieJob, CarBaoFeiJob carBaoFeiJob,
                       CarLiChengMonthJob carLiChengMonthJob, CarWuDanYongCheJob carWuDanYongCheJob,
@@ -52,7 +54,7 @@ public class JobService {
                       CarNianJianFeiJob carNianJianFeiJob, CarQiTaJob carQiTaJob, CarFeeHbJob carFeeHbJob,
                       CarFeeBsJob carFeeBsJob, HouseBuildingRepairMonthJob houseBuildingRepairMonthJob,
                       CarLiChengDayJob carLiChengDayJob, CarSiCheGongYongJob carSiCheGongYongJob,
-                      HouseRentInRepairMonthJob houseRentInRepairMonthJob) {
+                      HouseRentInRepairMonthJob houseRentInRepairMonthJob, CarReportJob carReportJob) {
         this.carBaseDataDayJob = carBaseDataDayJob;
         this.carYueJieJob = carYueJieJob;
         this.carBaoFeiJob = carBaoFeiJob;
@@ -72,6 +74,7 @@ public class JobService {
         this.carLiChengDayJob = carLiChengDayJob;
         this.carSiCheGongYongJob = carSiCheGongYongJob;
         this.houseRentInRepairMonthJob = houseRentInRepairMonthJob;
+        this.carReportJob = carReportJob;
     }
 
     public R<Object> runJob(RunJobDto dto) {
@@ -95,6 +98,7 @@ public class JobService {
             case CAR_LI_CHENG_DAY_JOB -> carLiChengDayJob.runJob();
             case CAR_SI_CHE_GONG_YONG_JOB -> carSiCheGongYongJob.runJob();
             case HOUSE_RENT_IN_REPAIR_MONTH_JOB -> houseRentInRepairMonthJob.runJob();
+            case CAR_REPORT_JOB -> carReportJob.runJob();
             default -> {}
         }
         return R.ok();

+ 3 - 3
src/main/java/com/nokia/finance/tasks/service/car/CarService.java

@@ -199,12 +199,12 @@ public class CarService {
      */
     public String getThirdUnit(String unit, String secondUnit) {
         if (!StringUtils.hasText(unit)) {
-            return "";
+            return secondUnit;
         }
-        if (secondUnit == null) {
+        String[] a = unit.split("_");
+        if (a.length == 1) {
             return unit;
         }
-        String[] a = unit.split("_");
         if (a.length < 4) {
             return secondUnit;
         }

+ 79 - 0
src/main/java/com/nokia/finance/tasks/service/common/file/FileService.java

@@ -0,0 +1,79 @@
+package com.nokia.finance.tasks.service.common.file;
+
+import cn.hutool.core.util.IdUtil;
+
+import java.io.InputStream;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public interface FileService {
+    /**
+     * 生成文件名
+     *
+     * @return {@link String}
+     */
+    default String generateFilename() {
+        return generateFilename("");
+    }
+
+    /**
+     * 生成文件名
+     *
+     * @param suffix 后缀
+     * @return {@link String}
+     */
+    default String generateFilename(String suffix) {
+        LocalDateTime now = LocalDateTime.now();
+        return now.getYear() + "/" + now.getMonthValue() + "/" + now.getDayOfMonth() + "/"
+                + IdUtil.fastSimpleUUID() + "-" + now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + suffix;
+    }
+
+    /**
+     * 获取下载地址
+     *
+     * @param object 对象名称
+     * @return {@link String}
+     */
+    String getDownloadUrl(String object);
+
+    /**
+     * 获取下载地址
+     *
+     * @param object   对象名称
+     * @param duration 过期时间
+     * @param unit     单位
+     * @return {@link String}
+     */
+    String getDownloadUrl(String object, int duration, TimeUnit unit);
+
+    /**
+     * 从流中上传数据到对象
+     *
+     * @param object     对象名称
+     * @param stream     流
+     * @param objectSize 对象大小
+     * @param tags       标签
+     * @return {@link Map}<{@link String}, {@link Object}>
+     */
+    Map<String, Object> putObject(String object, InputStream stream, long objectSize, Map<String, String> tags);
+    /**
+     * 从流中上传数据到对象
+     *
+     * @param object     对象名称
+     * @param stream     流
+     * @param objectSize 对象大小
+     * @return {@link Map}<{@link String}, {@link Object}>
+     */
+    default Map<String, Object> putObject(String object, InputStream stream, long objectSize) {
+        return putObject(object, stream, objectSize, null);
+    }
+
+    /**
+     * 获取存储桶名称
+     *
+     * @return {@link String}
+     */
+    String getBucket();
+}

+ 118 - 0
src/main/java/com/nokia/finance/tasks/service/common/file/MinioServiceImpl.java

@@ -0,0 +1,118 @@
+package com.nokia.finance.tasks.service.common.file;
+
+import com.nokia.finance.tasks.common.exception.MyRuntimeException;
+import com.nokia.finance.tasks.config.MinioConfig;
+import io.minio.GetPresignedObjectUrlArgs;
+import io.minio.MinioClient;
+import io.minio.ObjectWriteResponse;
+import io.minio.PutObjectArgs;
+import io.minio.errors.ErrorResponseException;
+import io.minio.errors.InsufficientDataException;
+import io.minio.errors.InternalException;
+import io.minio.errors.InvalidResponseException;
+import io.minio.errors.ServerException;
+import io.minio.errors.XmlParserException;
+import io.minio.http.Method;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@Primary
+@Slf4j
+@Service
+public class MinioServiceImpl implements FileService {
+
+    private final MinioClient minioClient;
+    private final MinioConfig minioConfig;
+
+    public MinioServiceImpl(MinioClient minioClient, MinioConfig minioConfig) {
+        this.minioClient = minioClient;
+        this.minioConfig = minioConfig;
+    }
+
+    /**
+     * 获取下载地址
+     *
+     * @param object 对象名称
+     * @return {@link String}
+     */
+    @Override
+    public String getDownloadUrl(String object) {
+        return getDownloadUrl(object, minioConfig.getExpiry(), TimeUnit.MINUTES);
+    }
+
+    /**
+     * 获取下载地址
+     *
+     * @param object   对象名称
+     * @param duration 过期时间
+     * @param unit     单位
+     * @return {@link String}
+     */
+    @Override
+    public String getDownloadUrl(String object, int duration, TimeUnit unit) {
+        try {
+            return StringUtils.delete(minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
+                    .expiry(duration, unit)
+                    .bucket(minioConfig.getBucket())
+                    .object(object)
+                    .method(Method.GET)
+                    .build()), minioConfig.getEndpoint());
+        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
+                 InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException |
+                 ServerException e) {
+            throw new MyRuntimeException(e);
+        }
+    }
+
+    /**
+     * 从流中上传数据到对象
+     *
+     * @param object     对象名称
+     * @param stream     流
+     * @param objectSize 对象大小
+     * @return {@link Map}<{@link String}, {@link Object}>
+     */
+    @Override
+    public Map<String, Object> putObject(String object, InputStream stream, long objectSize, Map<String, String> tags) {
+        try {
+            ObjectWriteResponse response = minioClient.putObject(PutObjectArgs.builder()
+                    .bucket(minioConfig.getBucket())
+                    .object(object)
+                    .stream(stream, objectSize, -1)
+                    .tags(tags)
+                    .build());
+            Map<String, Object> map = new HashMap<>();
+            map.put("object", response.object());
+            map.put("bucket", response.bucket());
+            map.put("etag", response.etag());
+            map.put("versionId", response.versionId());
+            map.put("headers", response.headers());
+            map.put("region", response.region());
+            return map;
+        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
+                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
+                 XmlParserException e) {
+            throw new MyRuntimeException(e);
+        }
+    }
+
+    /**
+     * 获取存储桶名称
+     *
+     * @return {@link String}
+     */
+    @Override
+    public String getBucket() {
+        return minioConfig.getBucket();
+    }
+}

+ 60 - 0
src/main/java/com/nokia/finance/tasks/utils/OfficeUtil.java

@@ -0,0 +1,60 @@
+package com.nokia.finance.tasks.utils;
+
+import com.nokia.finance.tasks.common.exception.MyRuntimeException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.springframework.util.StringUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.time.Duration;
+
+/**
+ * libreoffice工具
+ */
+@Slf4j
+public class OfficeUtil {
+
+    /**
+     * 转pdf
+     * @param outDir 输出文件夹
+     * @param files 输入文件
+     * @param timeout 超时分钟
+     */
+    public static void toPdf(String outDir, String files, Long timeout) {
+        String command = "docker exec libreoffice soffice --headless --convert-to pdf --outdir";
+        CommandLine commandLine = CommandLine.parse(command);
+        commandLine.addArgument(outDir);
+        commandLine.addArgument(files);
+        log.info("command: {}", commandLine);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ByteArrayOutputStream err = new ByteArrayOutputStream();
+        DefaultExecutor executor = DefaultExecutor.builder().get();
+        ExecuteWatchdog watchdog = ExecuteWatchdog.builder().setTimeout(Duration.ofMinutes(timeout)).get();
+        executor.setWatchdog(watchdog);
+        PumpStreamHandler streamHandler = new PumpStreamHandler(out, err);
+        executor.setStreamHandler(streamHandler);
+        try {
+            int exitValue = executor.execute(commandLine);
+            log.info("exitValue: {}", exitValue);
+            String errString = err.toString();
+            if (StringUtils.hasText(errString)) {
+                throw new MyRuntimeException();
+            }
+        } catch (Exception e) {
+            if (watchdog.killedProcess()) {
+                throw new MyRuntimeException("执行超时", e);
+            }
+            throw new MyRuntimeException(e);
+        } finally {
+            String outString = out.toString();
+            String errString = err.toString();
+            log.info("out: {}", outString);
+            if (StringUtils.hasText(errString)) {
+                log.error("err: {}", errString);
+            }
+        }
+    }
+}

+ 35 - 0
src/main/java/com/nokia/finance/tasks/utils/ZipUtil.java

@@ -0,0 +1,35 @@
+package com.nokia.finance.tasks.utils;
+
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+public class ZipUtil {
+    /**
+     * zip压缩文件夹不包括文件夹本身
+     * @param inputDir 文件夹
+     * @param outputFile 压缩文件
+     */
+    public static void zipDirNonSelf(Path inputDir, Path outputFile) throws IOException {
+        try (ZipArchiveOutputStream os = new ZipArchiveOutputStream(Files.newOutputStream(outputFile))) {
+            os.setLevel(9);
+            Files.walkFileTree(inputDir, new SimpleFileVisitor<>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                    String relativePath = inputDir.relativize(file).toString();
+                    ZipArchiveEntry entry = new ZipArchiveEntry(file.toFile(), relativePath);
+                    os.putArchiveEntry(entry);
+                    Files.copy(file, os);
+                    os.closeArchiveEntry();
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+    }
+}

+ 62 - 6
src/main/resources/application-dev.yml

@@ -7,16 +7,24 @@ logging:
 spring:
   datasource:
     driver-class-name: org.postgresql.Driver
-#    username: postgres
-#    password: Test!234
+    username: postgres
+    password: Test!234
 #    url: jdbc:postgresql://127.0.0.1:5432/financialdb
-#    url: jdbc:postgresql://192.168.65.128:5432/financialdb
-    url: jdbc:postgresql://172.16.107.5:5432/financialdb
-    username: finance
-    password: Finance@unicom23
+    url: jdbc:postgresql://192.168.65.128:5432/financialdb
+#    url: jdbc:postgresql://172.16.107.5:5432/financialdb
+#    username: finance
+#    password: Finance@unicom23
 #    url: jdbc:postgresql://192.168.50.3:15432/financialdb
 #    username: postgres
 #    password: NFQCgBA6YhNvgAqG6THw
+minio:
+  accessKey: house-car
+  bucket: house-car
+#  endpoint: http://192.168.10.7:19000/
+#  endpoint: http://127.0.0.1:19000/
+  endpoint: http://192.168.65.128:19000/
+  expiry: 15
+  secretKey: EGqIq7zKZwfasMQ5eLIoLId631vmLaal
 job:
   config:
     # copy脚本路径
@@ -130,3 +138,51 @@ job:
     car-fu-wu-fei-source-path: data/jzftp/HE_M_MTC_VEHICLE_CHARGE/
     # 河北成本管理系统车辆服务费数据归档路径
     car-fu-wu-fei-history-path: data/history/jzftp/HE_M_MTC_VEHICLE_CHARGE/
+# 车辆报告配置
+car-report:
+  # docx文件夹
+  docx-dir: templates/car/report/docx
+  # 输出路径
+  out-dir: /app/libreoffice/
+  # 输出docx路径
+  docx: /app/libreoffice/car.docx
+  # 输出pdf路径
+  pdf: /app/libreoffice/car.pdf
+  # ftl文件夹
+  ftl-dir: templates/car/report/ftls
+  # document ftl路径
+  document-ftl: document.ftl
+  # 北十占收比图表ftl路径
+  bszsb-chart-ftl: chart1.ftl
+  # 1-12月百公里燃油费变化情况图表ftl路径
+  bglry-qs-chart-ftl: chart2.ftl
+  # 二级组织机构百公里燃油图表ftl路径
+  bglry-unit-chart-ftl: chart3.ftl
+  # 1-12月维修费变化情况图表ftl路径
+  wx-qs-chart-ftl: chart4.ftl
+  # 二级组织机构自有车辆单车维修费图表ftl路径
+  wx-unit-chart-ftl: chart5.ftl
+  # document xml路径
+  document-xml: templates/car/report/docx/word/document.xml
+  # 北十占收比图表xml路径
+  bszsb-chart-xml: templates/car/report/docx/word/charts/chart1.xml
+  # 1-12月百公里燃油费变化情况图表xml路径
+  bglry-qs-chart-xml: templates/car/report/docx/word/charts/chart2.xml
+  # 二级组织机构百公里燃油图表xml路径
+  bglry-unit-chart-xml: templates/car/report/docx/word/charts/chart3.xml
+  # 1-12月维修费变化情况图表xml路径
+  wx-qs-chart-xml: templates/car/report/docx/word/charts/chart4.xml
+  # 二级组织机构自有车辆单车维修费图表xml路径
+  wx-unit-chart-xml: templates/car/report/docx/word/charts/chart5.xml
+  # 建议更新车辆xlsx路径
+  jygx-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet.xlsx
+  # 燃油异常xlsx路径
+  ryyc-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet1.xlsx
+  # 自有车辆异常维修费xlsx路径
+  zywxyc-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet2.xlsx
+  # 低效车辆xlsx路径
+  dx-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet3.xlsx
+  # 违规用车xlsx路径
+  wg-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet4.xlsx
+  # 违章xlsx路径
+  wz-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet5.xlsx

+ 54 - 0
src/main/resources/application-prod.yml

@@ -10,6 +10,12 @@ spring:
     username: finance
     password: Finance@unicom23
     url: jdbc:postgresql://172.16.107.5:5432/financialdb
+minio:
+  accessKey: house-car
+  bucket: house-car
+  endpoint: http://172.16.107.4:39000/
+  expiry: 15
+  secretKey: pfhJVM9CUitr2rv1iGA0WQbCr4XdGJ2rmB7mgUaG
 job:
   config:
     # copy脚本路径
@@ -123,3 +129,51 @@ job:
     car-fu-wu-fei-source-path: /data/jzftp/HE_M_MTC_VEHICLE_CHARGE/
     # 河北成本管理系统车辆服务费数据归档路径
     car-fu-wu-fei-history-path: /data/history/jzftp/HE_M_MTC_VEHICLE_CHARGE/
+# 车辆报告配置
+car-report:
+  # docx文件夹
+  docx-dir: templates/car/report/docx
+  # 输出路径
+  out-dir: /app/libreoffice/
+  # 输出docx路径
+  docx: /app/libreoffice/car.docx
+  # 输出pdf路径
+  pdf: /app/libreoffice/car.pdf
+  # ftl文件夹
+  ftl-dir: templates/car/report/ftls
+  # document ftl路径
+  document-ftl: document.ftl
+  # 北十占收比图表ftl路径
+  bszsb-chart-ftl: chart1.ftl
+  # 1-12月百公里燃油费变化情况图表ftl路径
+  bglry-qs-chart-ftl: chart2.ftl
+  # 二级组织机构百公里燃油图表ftl路径
+  bglry-unit-chart-ftl: chart3.ftl
+  # 1-12月维修费变化情况图表ftl路径
+  wx-qs-chart-ftl: chart4.ftl
+  # 二级组织机构自有车辆单车维修费图表ftl路径
+  wx-unit-chart-ftl: chart5.ftl
+  # document xml路径
+  document-xml: templates/car/report/docx/word/document.xml
+  # 北十占收比图表xml路径
+  bszsb-chart-xml: templates/car/report/docx/word/charts/chart1.xml
+  # 1-12月百公里燃油费变化情况图表xml路径
+  bglry-qs-chart-xml: templates/car/report/docx/word/charts/chart2.xml
+  # 二级组织机构百公里燃油图表xml路径
+  bglry-unit-chart-xml: templates/car/report/docx/word/charts/chart3.xml
+  # 1-12月维修费变化情况图表xml路径
+  wx-qs-chart-xml: templates/car/report/docx/word/charts/chart4.xml
+  # 二级组织机构自有车辆单车维修费图表xml路径
+  wx-unit-chart-xml: templates/car/report/docx/word/charts/chart5.xml
+  # 建议更新车辆xlsx路径
+  jygx-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet.xlsx
+  # 燃油异常xlsx路径
+  ryyc-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet1.xlsx
+  # 自有车辆异常维修费xlsx路径
+  zywxyc-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet2.xlsx
+  # 低效车辆xlsx路径
+  dx-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet3.xlsx
+  # 违规用车xlsx路径
+  wg-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet4.xlsx
+  # 违章xlsx路径
+  wz-xlsx: templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet5.xlsx

+ 26 - 0
src/test/java/com/nokia/finance/tasks/MybatisPlusGeneratorTest.java

@@ -0,0 +1,26 @@
+package com.nokia.finance.tasks;
+
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+
+public class MybatisPlusGeneratorTest {
+    public static void main(String[] args) {
+        FastAutoGenerator.create(
+                new DataSourceConfig.Builder("jdbc:postgresql://172.16.107.5:5432/financialdb",
+                        "finance",
+                        "Finance@unicom23").schema("car"))
+                .globalConfig(builder -> {
+                    builder.outputDir("z:/").disableOpenDir();
+                })
+                .strategyConfig(builder -> {
+                    builder.addInclude("car_wei_zhang_chang_qi")
+                            .entityBuilder()
+                            .disableSerialVersionUID()
+                            .enableFileOverride()
+                            .enableLombok();
+                })
+                .templateEngine(new FreemarkerTemplateEngine())
+                .execute();
+    }
+}

+ 21 - 0
src/test/java/com/nokia/finance/tasks/car/CarReportJobTests.java

@@ -0,0 +1,21 @@
+package com.nokia.finance.tasks.car;
+
+import com.nokia.finance.tasks.jobs.car.CarReportJob;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+@Slf4j
+@SpringBootTest
+@ActiveProfiles("dev")
+class CarReportJobTests {
+    @Autowired
+    CarReportJob carReportJob;
+
+    @Test
+    void runJobTest() {
+        carReportJob.runJob();
+    }
+}

Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
templates/car/report/docx/[Content_Types].xml


+ 2 - 0
templates/car/report/docx/_rels/.rels

@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>

+ 2 - 0
templates/car/report/docx/customXml/_rels/item1.xml.rels

@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps" Target="itemProps1.xml"/></Relationships>

+ 1 - 0
templates/car/report/docx/customXml/item1.xml

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><s:customData xmlns="http://www.wps.cn/officeDocument/2013/wpsCustomData" xmlns:s="http://www.wps.cn/officeDocument/2013/wpsCustomData"><customSectProps><customSectPr/></customSectProps><customShpExts><customShpInfo spid="_x0000_s1026" textRotate="1"/><customShpInfo spid="_x0000_s1027"/><customShpInfo spid="_x0000_s1028"/><customShpInfo spid="_x0000_s1029"/><customShpInfo spid="_x0000_s1030"/><customShpInfo spid="_x0000_s1031"/><customShpInfo spid="_x0000_s1032"/></customShpExts></s:customData>

+ 2 - 0
templates/car/report/docx/customXml/itemProps1.xml

@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<ds:datastoreItem ds:itemID="{B1977F7D-205B-4081-913C-38D41E755F92}" xmlns:ds="http://schemas.openxmlformats.org/officeDocument/2006/customXml"><ds:schemaRefs><ds:schemaRef ds:uri="http://www.wps.cn/officeDocument/2013/wpsCustomData"/></ds:schemaRefs></ds:datastoreItem>

+ 19 - 0
templates/car/report/docx/docProps/app.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
+            xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
+    <Template>Normal.dotm</Template>
+    <TotalTime>0</TotalTime>
+    <Pages>12</Pages>
+    <Words>815</Words>
+    <Characters>4651</Characters>
+    <DocSecurity>0</DocSecurity>
+    <Lines>38</Lines>
+    <Paragraphs>10</Paragraphs>
+    <ScaleCrop>false</ScaleCrop>
+    <Company></Company>
+    <LinksUpToDate>false</LinksUpToDate>
+    <CharactersWithSpaces>5456</CharactersWithSpaces>
+    <SharedDoc>false</SharedDoc>
+    <HyperlinksChanged>false</HyperlinksChanged>
+    <AppVersion>16.0000</AppVersion>
+</Properties>

+ 12 - 0
templates/car/report/docx/docProps/core.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
+                   xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/"
+                   xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <dc:title></dc:title>
+    <dc:subject></dc:subject>
+    <dc:creator></dc:creator>
+    <dc:description></dc:description>
+    <cp:lastPrinted>2000-01-01T00:00:00Z</cp:lastPrinted>
+    <dcterms:created xsi:type="dcterms:W3CDTF">2000-01-01T00:00:00Z</dcterms:created>
+    <dcterms:modified xsi:type="dcterms:W3CDTF">2000-01-01T00:00:00Z</dcterms:modified>
+</cp:coreProperties>

+ 2 - 0
templates/car/report/docx/docProps/custom.xml

@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="ICV"><vt:lpwstr>5ADE5CEA709142E8A7DADA33FB9CF240</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="3" name="KSOProductBuildVer"><vt:lpwstr>2052-12.1.0.16729</vt:lpwstr></property></Properties>

Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
templates/car/report/docx/word/_rels/document.xml.rels


+ 290 - 0
templates/car/report/docx/word/charts/chart1.xml

@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
+              xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
+              xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
+              xmlns:c16r2="http://schemas.microsoft.com/office/drawing/2015/06/chart">
+    <c:date1904 val="1"/>
+    <c:lang val="zh-CN"/>
+    <c:roundedCorners val="0"/>
+    <c:style val="2"/>
+    <c:chart>
+        <c:title>
+            <c:tx>
+                <c:rich>
+                    <a:bodyPr rot="0"/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:r>
+                            <a:rPr lang="zh-CN" altLang="en-US" sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:rPr>
+                            <a:t>本年占收比</a:t>
+                        </a:r>
+                    </a:p>
+                </c:rich>
+            </c:tx>
+            <c:overlay val="0"/>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:title>
+        <c:autoTitleDeleted val="0"/>
+        <c:plotArea>
+            <c:layout/>
+            <c:barChart>
+                <c:barDir val="col"/>
+                <c:grouping val="clustered"/>
+                <c:varyColors val="0"/>
+                <c:ser>
+                    <c:idx val="0"/>
+                    <c:order val="0"/>
+                    <c:tx>
+                        <c:strRef>
+                            <c:f>label 0</c:f>
+                            <c:strCache>
+                                <c:ptCount val="1"/>
+                                <c:pt idx="0">
+                                    <c:v>本年占收比</c:v>
+                                </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:tx>
+                    <c:spPr>
+                        <a:solidFill>
+                            <a:srgbClr val="4472C4"/>
+                        </a:solidFill>
+                        <a:ln w="0">
+                            <a:noFill/>
+                        </a:ln>
+                    </c:spPr>
+                    <c:invertIfNegative val="0"/>
+                    <c:dLbls>
+                        <c:numFmt formatCode="0.000%" sourceLinked="0"/>
+                        <c:spPr>
+                            <a:noFill/>
+                            <a:ln>
+                                <a:noFill/>
+                            </a:ln>
+                            <a:effectLst/>
+                        </c:spPr>
+                        <c:txPr>
+                            <a:bodyPr wrap="square"/>
+                            <a:lstStyle/>
+                            <a:p>
+                                <a:pPr>
+                                    <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                        <a:solidFill>
+                                            <a:srgbClr val="404040"/>
+                                        </a:solidFill>
+                                        <a:latin typeface="等线"/>
+                                    </a:defRPr>
+                                </a:pPr>
+                                <a:endParaRPr lang="zh-CN"/>
+                            </a:p>
+                        </c:txPr>
+                        <c:dLblPos val="outEnd"/>
+                        <c:showLegendKey val="0"/>
+                        <c:showVal val="1"/>
+                        <c:showCatName val="0"/>
+                        <c:showSerName val="0"/>
+                        <c:showPercent val="0"/>
+                        <c:showBubbleSize val="1"/>
+                        <c:separator>;</c:separator>
+                        <c:showLeaderLines val="0"/>
+                        <c:extLst>
+                            <c:ext uri="{CE6537A1-D6FC-4f65-9D91-7224C49458BB}"
+                                   xmlns:c15="http://schemas.microsoft.com/office/drawing/2012/chart">
+                                <c15:showLeaderLines val="1"/>
+                            </c:ext>
+                        </c:extLst>
+                    </c:dLbls>
+                    <c:cat>
+                        <c:strRef>
+                            <c:f>categories</c:f>
+                            <c:strCache>
+                                <c:ptCount val="10"/>
+                                    <c:pt idx="0">
+                                        <c:v>北京</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>天津</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>山东</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>内蒙古</c:v>
+                                    </c:pt>
+                                    <c:pt idx="4">
+                                        <c:v>辽宁</c:v>
+                                    </c:pt>
+                                    <c:pt idx="5">
+                                        <c:v>吉林</c:v>
+                                    </c:pt>
+                                    <c:pt idx="6">
+                                        <c:v>河南</c:v>
+                                    </c:pt>
+                                    <c:pt idx="7">
+                                        <c:v>山西</c:v>
+                                    </c:pt>
+                                    <c:pt idx="8">
+                                        <c:v>河北</c:v>
+                                    </c:pt>
+                                    <c:pt idx="9">
+                                        <c:v>黑龙江</c:v>
+                                    </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:cat>
+                    <c:val>
+                        <c:numRef>
+                            <c:f>0</c:f>
+                            <c:numCache>
+                                <c:formatCode>0.000%</c:formatCode>
+                                <c:ptCount val="10"/>
+                                    <c:pt idx="0">
+                                        <c:v>0.00043</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>0.00075</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>0.00079</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>0.00221</c:v>
+                                    </c:pt>
+                                    <c:pt idx="4">
+                                        <c:v>0.00235</c:v>
+                                    </c:pt>
+                                    <c:pt idx="5">
+                                        <c:v>0.00239</c:v>
+                                    </c:pt>
+                                    <c:pt idx="6">
+                                        <c:v>0.00246</c:v>
+                                    </c:pt>
+                                    <c:pt idx="7">
+                                        <c:v>0.00316</c:v>
+                                    </c:pt>
+                                    <c:pt idx="8">
+                                        <c:v>0.00351</c:v>
+                                    </c:pt>
+                                    <c:pt idx="9">
+                                        <c:v>0.00501</c:v>
+                                    </c:pt>
+                            </c:numCache>
+                        </c:numRef>
+                    </c:val>
+                    <c:extLst>
+                        <c:ext uri="{C3380CC4-5D6E-409C-BE32-E72D297353CC}"
+                               xmlns:c16="http://schemas.microsoft.com/office/drawing/2014/chart">
+                            <c16:uniqueId val="{00000000-6A0B-41EA-832E-F5C1F497AF0B}"/>
+                        </c:ext>
+                    </c:extLst>
+                </c:ser>
+                <c:dLbls>
+                    <c:showLegendKey val="0"/>
+                    <c:showVal val="0"/>
+                    <c:showCatName val="0"/>
+                    <c:showSerName val="0"/>
+                    <c:showPercent val="0"/>
+                    <c:showBubbleSize val="0"/>
+                </c:dLbls>
+                <c:gapWidth val="219"/>
+                <c:overlap val="-27"/>
+                <c:axId val="84730512"/>
+                <c:axId val="32703904"/>
+            </c:barChart>
+            <c:catAx>
+                <c:axId val="84730512"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="0"/>
+                <c:axPos val="b"/>
+                <c:numFmt formatCode="General" sourceLinked="0"/>
+                <c:majorTickMark val="out"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:spPr>
+                    <a:ln w="9360">
+                        <a:solidFill>
+                            <a:srgbClr val="D9D9D9"/>
+                        </a:solidFill>
+                        <a:round/>
+                    </a:ln>
+                </c:spPr>
+                <c:txPr>
+                    <a:bodyPr/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:endParaRPr lang="zh-CN"/>
+                    </a:p>
+                </c:txPr>
+                <c:crossAx val="32703904"/>
+                <c:crosses val="autoZero"/>
+                <c:auto val="1"/>
+                <c:lblAlgn val="ctr"/>
+                <c:lblOffset val="100"/>
+                <c:noMultiLvlLbl val="0"/>
+            </c:catAx>
+            <c:valAx>
+                <c:axId val="32703904"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="1"/>
+                <c:axPos val="l"/>
+                <c:numFmt formatCode="General" sourceLinked="1"/>
+                <c:majorTickMark val="out"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:crossAx val="84730512"/>
+                <c:crosses val="autoZero"/>
+                <c:crossBetween val="between"/>
+            </c:valAx>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:plotArea>
+        <c:plotVisOnly val="1"/>
+        <c:dispBlanksAs val="gap"/>
+        <c:showDLblsOverMax val="1"/>
+    </c:chart>
+    <c:spPr>
+        <a:solidFill>
+            <a:srgbClr val="FFFFFF"/>
+        </a:solidFill>
+        <a:ln w="9360">
+            <a:solidFill>
+                <a:srgbClr val="D9D9D9"/>
+            </a:solidFill>
+            <a:round/>
+        </a:ln>
+    </c:spPr>
+</c:chartSpace>

+ 304 - 0
templates/car/report/docx/word/charts/chart2.xml

@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
+              xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
+              xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
+              xmlns:c16r2="http://schemas.microsoft.com/office/drawing/2015/06/chart">
+    <c:date1904 val="1"/>
+    <c:lang val="zh-CN"/>
+    <c:roundedCorners val="0"/>
+    <c:style val="2"/>
+    <c:chart>
+        <c:title>
+            <c:tx>
+                <c:rich>
+                    <a:bodyPr rot="0"/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:r>
+                            <a:rPr lang="zh-CN" altLang="en-US" sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:rPr>
+                            <a:t>百公里油费(元</a:t>
+                        </a:r>
+                        <a:r>
+                            <a:rPr lang="en-US" altLang="zh-CN" sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:rPr>
+                            <a:t>/</a:t>
+                        </a:r>
+                        <a:r>
+                            <a:rPr lang="zh-CN" altLang="en-US" sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:rPr>
+                            <a:t>百公里)</a:t>
+                        </a:r>
+                    </a:p>
+                </c:rich>
+            </c:tx>
+            <c:overlay val="0"/>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:title>
+        <c:autoTitleDeleted val="0"/>
+        <c:plotArea>
+            <c:layout/>
+            <c:lineChart>
+                <c:grouping val="standard"/>
+                <c:varyColors val="0"/>
+                <c:ser>
+                    <c:idx val="0"/>
+                    <c:order val="0"/>
+                    <c:tx>
+                        <c:strRef>
+                            <c:f>label 0</c:f>
+                            <c:strCache>
+                                <c:ptCount val="1"/>
+                                <c:pt idx="0">
+                                    <c:v>百公里油费(元/百公里)</c:v>
+                                </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:tx>
+                    <c:spPr>
+                        <a:ln w="28440" cap="rnd">
+                            <a:solidFill>
+                                <a:srgbClr val="4472C4"/>
+                            </a:solidFill>
+                            <a:round/>
+                        </a:ln>
+                    </c:spPr>
+                    <c:marker>
+                        <c:symbol val="none"/>
+                    </c:marker>
+                    <c:dLbls>
+                        <c:numFmt formatCode="#,##0.0" sourceLinked="0"/>
+                        <c:spPr>
+                            <a:noFill/>
+                            <a:ln>
+                                <a:noFill/>
+                            </a:ln>
+                            <a:effectLst/>
+                        </c:spPr>
+                        <c:txPr>
+                            <a:bodyPr wrap="square"/>
+                            <a:lstStyle/>
+                            <a:p>
+                                <a:pPr>
+                                    <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                        <a:solidFill>
+                                            <a:srgbClr val="404040"/>
+                                        </a:solidFill>
+                                        <a:latin typeface="等线"/>
+                                    </a:defRPr>
+                                </a:pPr>
+                                <a:endParaRPr lang="zh-CN"/>
+                            </a:p>
+                        </c:txPr>
+                        <c:dLblPos val="t"/>
+                        <c:showLegendKey val="0"/>
+                        <c:showVal val="1"/>
+                        <c:showCatName val="0"/>
+                        <c:showSerName val="0"/>
+                        <c:showPercent val="0"/>
+                        <c:showBubbleSize val="1"/>
+                        <c:separator>;</c:separator>
+                        <c:showLeaderLines val="0"/>
+                        <c:extLst>
+                            <c:ext uri="{CE6537A1-D6FC-4f65-9D91-7224C49458BB}"
+                                   xmlns:c15="http://schemas.microsoft.com/office/drawing/2012/chart">
+                                <c15:showLeaderLines val="1"/>
+                            </c:ext>
+                        </c:extLst>
+                    </c:dLbls>
+                    <c:cat>
+                        <c:strRef>
+                            <c:f>categories</c:f>
+                            <c:strCache>
+                                <c:ptCount val="12"/>
+                                <c:pt idx="0">
+                                    <c:v>1月</c:v>
+                                </c:pt>
+                                <c:pt idx="1">
+                                    <c:v>2月</c:v>
+                                </c:pt>
+                                <c:pt idx="2">
+                                    <c:v>3月</c:v>
+                                </c:pt>
+                                <c:pt idx="3">
+                                    <c:v>4月</c:v>
+                                </c:pt>
+                                <c:pt idx="4">
+                                    <c:v>5月</c:v>
+                                </c:pt>
+                                <c:pt idx="5">
+                                    <c:v>6月</c:v>
+                                </c:pt>
+                                <c:pt idx="6">
+                                    <c:v>7月</c:v>
+                                </c:pt>
+                                <c:pt idx="7">
+                                    <c:v>8月</c:v>
+                                </c:pt>
+                                <c:pt idx="8">
+                                    <c:v>9月</c:v>
+                                </c:pt>
+                                <c:pt idx="9">
+                                    <c:v>10月</c:v>
+                                </c:pt>
+                                <c:pt idx="10">
+                                    <c:v>11月</c:v>
+                                </c:pt>
+                                <c:pt idx="11">
+                                    <c:v>12月</c:v>
+                                </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:cat>
+                    <c:val>
+                        <c:numRef>
+                            <c:f>0</c:f>
+                            <c:numCache>
+                                <c:formatCode>#,##0.0</c:formatCode>
+                                <c:ptCount val="12"/>
+                                                                    <c:pt idx="0">
+                                        <c:v>199.56</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>308.66</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>139.82</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>175.70</c:v>
+                                    </c:pt>
+                            </c:numCache>
+                        </c:numRef>
+                    </c:val>
+                    <c:smooth val="0"/>
+                    <c:extLst>
+                        <c:ext uri="{C3380CC4-5D6E-409C-BE32-E72D297353CC}"
+                               xmlns:c16="http://schemas.microsoft.com/office/drawing/2014/chart">
+                            <c16:uniqueId val="{00000000-8852-459A-AD8C-5336AE2269F1}"/>
+                        </c:ext>
+                    </c:extLst>
+                </c:ser>
+                <c:dLbls>
+                    <c:showLegendKey val="0"/>
+                    <c:showVal val="0"/>
+                    <c:showCatName val="0"/>
+                    <c:showSerName val="0"/>
+                    <c:showPercent val="0"/>
+                    <c:showBubbleSize val="0"/>
+                </c:dLbls>
+                <c:hiLowLines>
+                    <c:spPr>
+                        <a:ln w="0">
+                            <a:noFill/>
+                        </a:ln>
+                    </c:spPr>
+                </c:hiLowLines>
+                <c:smooth val="0"/>
+                <c:axId val="46175464"/>
+                <c:axId val="42022836"/>
+            </c:lineChart>
+            <c:catAx>
+                <c:axId val="46175464"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="0"/>
+                <c:axPos val="b"/>
+                <c:numFmt formatCode="General" sourceLinked="0"/>
+                <c:majorTickMark val="out"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:spPr>
+                    <a:ln w="9360">
+                        <a:solidFill>
+                            <a:srgbClr val="D9D9D9"/>
+                        </a:solidFill>
+                        <a:round/>
+                    </a:ln>
+                </c:spPr>
+                <c:txPr>
+                    <a:bodyPr/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:endParaRPr lang="zh-CN"/>
+                    </a:p>
+                </c:txPr>
+                <c:crossAx val="42022836"/>
+                <c:crosses val="autoZero"/>
+                <c:auto val="1"/>
+                <c:lblAlgn val="ctr"/>
+                <c:lblOffset val="100"/>
+                <c:noMultiLvlLbl val="0"/>
+            </c:catAx>
+            <c:valAx>
+                <c:axId val="42022836"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="1"/>
+                <c:axPos val="l"/>
+                <c:numFmt formatCode="General" sourceLinked="1"/>
+                <c:majorTickMark val="out"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:crossAx val="46175464"/>
+                <c:crosses val="autoZero"/>
+                <c:crossBetween val="between"/>
+            </c:valAx>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:plotArea>
+        <c:plotVisOnly val="1"/>
+        <c:dispBlanksAs val="gap"/>
+        <c:showDLblsOverMax val="1"/>
+    </c:chart>
+    <c:spPr>
+        <a:solidFill>
+            <a:srgbClr val="FFFFFF"/>
+        </a:solidFill>
+        <a:ln w="9360">
+            <a:solidFill>
+                <a:srgbClr val="D9D9D9"/>
+            </a:solidFill>
+            <a:round/>
+        </a:ln>
+    </c:spPr>
+</c:chartSpace>

+ 314 - 0
templates/car/report/docx/word/charts/chart3.xml

@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
+              xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
+              xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
+              xmlns:c16r2="http://schemas.microsoft.com/office/drawing/2015/06/chart">
+    <c:date1904 val="1"/>
+    <c:lang val="zh-CN"/>
+    <c:roundedCorners val="0"/>
+    <c:style val="2"/>
+    <c:chart>
+        <c:title>
+            <c:tx>
+                <c:rich>
+                    <a:bodyPr rot="0"/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:r>
+                            <a:rPr lang="zh-CN" altLang="en-US" sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:rPr>
+                            <a:t>百公里燃油费(元)</a:t>
+                        </a:r>
+                    </a:p>
+                </c:rich>
+            </c:tx>
+            <c:overlay val="0"/>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:title>
+        <c:autoTitleDeleted val="0"/>
+        <c:plotArea>
+            <c:layout/>
+            <c:barChart>
+                <c:barDir val="col"/>
+                <c:grouping val="clustered"/>
+                <c:varyColors val="0"/>
+                <c:ser>
+                    <c:idx val="0"/>
+                    <c:order val="0"/>
+                    <c:tx>
+                        <c:strRef>
+                            <c:f>label 0</c:f>
+                            <c:strCache>
+                                <c:ptCount val="1"/>
+                                <c:pt idx="0">
+                                    <c:v>百公里燃油费(元)</c:v>
+                                </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:tx>
+                    <c:spPr>
+                        <a:solidFill>
+                            <a:srgbClr val="4472C4"/>
+                        </a:solidFill>
+                        <a:ln w="0">
+                            <a:noFill/>
+                        </a:ln>
+                    </c:spPr>
+                    <c:invertIfNegative val="0"/>
+                    <c:dLbls>
+                        <c:numFmt formatCode="#,##0" sourceLinked="0"/>
+                        <c:spPr>
+                            <a:noFill/>
+                            <a:ln>
+                                <a:noFill/>
+                            </a:ln>
+                            <a:effectLst/>
+                        </c:spPr>
+                        <c:txPr>
+                            <a:bodyPr wrap="square"/>
+                            <a:lstStyle/>
+                            <a:p>
+                                <a:pPr>
+                                    <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                        <a:solidFill>
+                                            <a:srgbClr val="404040"/>
+                                        </a:solidFill>
+                                        <a:latin typeface="等线"/>
+                                    </a:defRPr>
+                                </a:pPr>
+                                <a:endParaRPr lang="zh-CN"/>
+                            </a:p>
+                        </c:txPr>
+                        <c:dLblPos val="outEnd"/>
+                        <c:showLegendKey val="0"/>
+                        <c:showVal val="1"/>
+                        <c:showCatName val="0"/>
+                        <c:showSerName val="0"/>
+                        <c:showPercent val="0"/>
+                        <c:showBubbleSize val="1"/>
+                        <c:separator>;</c:separator>
+                        <c:showLeaderLines val="0"/>
+                        <c:extLst>
+                            <c:ext uri="{CE6537A1-D6FC-4f65-9D91-7224C49458BB}"
+                                   xmlns:c15="http://schemas.microsoft.com/office/drawing/2012/chart">
+                                <c15:showLeaderLines val="1"/>
+                            </c:ext>
+                        </c:extLst>
+                    </c:dLbls>
+                    <c:cat>
+                        <c:strRef>
+                            <c:f>categories</c:f>
+                            <c:strCache>
+                                <c:ptCount val="14"/>
+                                    <c:pt idx="0">
+                                        <c:v>秦皇岛</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>衡水</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>承德</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>雄安</c:v>
+                                    </c:pt>
+                                    <c:pt idx="4">
+                                        <c:v>石家庄</c:v>
+                                    </c:pt>
+                                    <c:pt idx="5">
+                                        <c:v>邢台</c:v>
+                                    </c:pt>
+                                    <c:pt idx="6">
+                                        <c:v>沧州</c:v>
+                                    </c:pt>
+                                    <c:pt idx="7">
+                                        <c:v>唐山</c:v>
+                                    </c:pt>
+                                    <c:pt idx="8">
+                                        <c:v>张家口</c:v>
+                                    </c:pt>
+                                    <c:pt idx="9">
+                                        <c:v>廊坊</c:v>
+                                    </c:pt>
+                                    <c:pt idx="10">
+                                        <c:v>平均</c:v>
+                                    </c:pt>
+                                    <c:pt idx="11">
+                                        <c:v>保定</c:v>
+                                    </c:pt>
+                                    <c:pt idx="12">
+                                        <c:v>邯郸</c:v>
+                                    </c:pt>
+                                    <c:pt idx="13">
+                                        <c:v>机动局</c:v>
+                                    </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:cat>
+                    <c:val>
+                        <c:numRef>
+                            <c:f>0</c:f>
+                            <c:numCache>
+                                <c:formatCode>#,##0</c:formatCode>
+                                <c:ptCount val="14"/>
+                                    <c:pt idx="0">
+                                        <c:v>68.21</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>71.08</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>71.80</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>74.15</c:v>
+                                    </c:pt>
+                                    <c:pt idx="4">
+                                        <c:v>75.25</c:v>
+                                    </c:pt>
+                                    <c:pt idx="5">
+                                        <c:v>76.23</c:v>
+                                    </c:pt>
+                                    <c:pt idx="6">
+                                        <c:v>76.94</c:v>
+                                    </c:pt>
+                                    <c:pt idx="7">
+                                        <c:v>78.11</c:v>
+                                    </c:pt>
+                                    <c:pt idx="8">
+                                        <c:v>80.68</c:v>
+                                    </c:pt>
+                                    <c:pt idx="9">
+                                        <c:v>83.73</c:v>
+                                    </c:pt>
+                                    <c:pt idx="10">
+                                        <c:v>83.99</c:v>
+                                    </c:pt>
+                                    <c:pt idx="11">
+                                        <c:v>99.22</c:v>
+                                    </c:pt>
+                                    <c:pt idx="12">
+                                        <c:v>108.71</c:v>
+                                    </c:pt>
+                                    <c:pt idx="13">
+                                        <c:v>127.73</c:v>
+                                    </c:pt>
+                            </c:numCache>
+                        </c:numRef>
+                    </c:val>
+                    <c:extLst>
+                        <c:ext uri="{C3380CC4-5D6E-409C-BE32-E72D297353CC}"
+                               xmlns:c16="http://schemas.microsoft.com/office/drawing/2014/chart">
+                            <c16:uniqueId val="{00000000-79B2-48A4-A202-6A1E161748C0}"/>
+                        </c:ext>
+                    </c:extLst>
+                </c:ser>
+                <c:dLbls>
+                    <c:showLegendKey val="0"/>
+                    <c:showVal val="0"/>
+                    <c:showCatName val="0"/>
+                    <c:showSerName val="0"/>
+                    <c:showPercent val="0"/>
+                    <c:showBubbleSize val="0"/>
+                </c:dLbls>
+                <c:gapWidth val="219"/>
+                <c:overlap val="-27"/>
+                <c:axId val="55240929"/>
+                <c:axId val="38409553"/>
+            </c:barChart>
+            <c:catAx>
+                <c:axId val="55240929"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="0"/>
+                <c:axPos val="b"/>
+                <c:numFmt formatCode="General" sourceLinked="0"/>
+                <c:majorTickMark val="none"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:spPr>
+                    <a:ln w="9360">
+                        <a:solidFill>
+                            <a:srgbClr val="D9D9D9"/>
+                        </a:solidFill>
+                        <a:round/>
+                    </a:ln>
+                </c:spPr>
+                <c:txPr>
+                    <a:bodyPr/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:endParaRPr lang="zh-CN"/>
+                    </a:p>
+                </c:txPr>
+                <c:crossAx val="38409553"/>
+                <c:crosses val="autoZero"/>
+                <c:auto val="1"/>
+                <c:lblAlgn val="ctr"/>
+                <c:lblOffset val="100"/>
+                <c:noMultiLvlLbl val="0"/>
+            </c:catAx>
+            <c:valAx>
+                <c:axId val="38409553"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="1"/>
+                <c:axPos val="l"/>
+                <c:numFmt formatCode="General" sourceLinked="1"/>
+                <c:majorTickMark val="none"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:crossAx val="55240929"/>
+                <c:crosses val="autoZero"/>
+                <c:crossBetween val="between"/>
+            </c:valAx>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:plotArea>
+        <c:plotVisOnly val="1"/>
+        <c:dispBlanksAs val="gap"/>
+        <c:showDLblsOverMax val="1"/>
+    </c:chart>
+    <c:spPr>
+        <a:solidFill>
+            <a:srgbClr val="FFFFFF"/>
+        </a:solidFill>
+        <a:ln w="9360">
+            <a:solidFill>
+                <a:srgbClr val="D9D9D9"/>
+            </a:solidFill>
+            <a:round/>
+        </a:ln>
+    </c:spPr>
+</c:chartSpace>

+ 286 - 0
templates/car/report/docx/word/charts/chart4.xml

@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
+              xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
+              xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
+              xmlns:c16r2="http://schemas.microsoft.com/office/drawing/2015/06/chart">
+    <c:date1904 val="1"/>
+    <c:lang val="zh-CN"/>
+    <c:roundedCorners val="0"/>
+    <c:style val="2"/>
+    <c:chart>
+        <c:title>
+            <c:tx>
+                <c:rich>
+                    <a:bodyPr rot="0"/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:r>
+                            <a:rPr lang="zh-CN" altLang="en-US" sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:rPr>
+                            <a:t>维修费(万元)</a:t>
+                        </a:r>
+                    </a:p>
+                </c:rich>
+            </c:tx>
+            <c:overlay val="0"/>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:title>
+        <c:autoTitleDeleted val="0"/>
+        <c:plotArea>
+            <c:layout/>
+            <c:lineChart>
+                <c:grouping val="standard"/>
+                <c:varyColors val="0"/>
+                <c:ser>
+                    <c:idx val="0"/>
+                    <c:order val="0"/>
+                    <c:tx>
+                        <c:strRef>
+                            <c:f>label 0</c:f>
+                            <c:strCache>
+                                <c:ptCount val="1"/>
+                                <c:pt idx="0">
+                                    <c:v>维修费(万元)</c:v>
+                                </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:tx>
+                    <c:spPr>
+                        <a:ln w="28440" cap="rnd">
+                            <a:solidFill>
+                                <a:srgbClr val="4472C4"/>
+                            </a:solidFill>
+                            <a:round/>
+                        </a:ln>
+                    </c:spPr>
+                    <c:marker>
+                        <c:symbol val="none"/>
+                    </c:marker>
+                    <c:dLbls>
+                        <c:numFmt formatCode="#,##0.00" sourceLinked="0"/>
+                        <c:spPr>
+                            <a:noFill/>
+                            <a:ln>
+                                <a:noFill/>
+                            </a:ln>
+                            <a:effectLst/>
+                        </c:spPr>
+                        <c:txPr>
+                            <a:bodyPr wrap="square"/>
+                            <a:lstStyle/>
+                            <a:p>
+                                <a:pPr>
+                                    <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                        <a:solidFill>
+                                            <a:srgbClr val="404040"/>
+                                        </a:solidFill>
+                                        <a:latin typeface="等线"/>
+                                    </a:defRPr>
+                                </a:pPr>
+                                <a:endParaRPr lang="zh-CN"/>
+                            </a:p>
+                        </c:txPr>
+                        <c:dLblPos val="t"/>
+                        <c:showLegendKey val="0"/>
+                        <c:showVal val="1"/>
+                        <c:showCatName val="0"/>
+                        <c:showSerName val="0"/>
+                        <c:showPercent val="0"/>
+                        <c:showBubbleSize val="1"/>
+                        <c:separator>;</c:separator>
+                        <c:showLeaderLines val="0"/>
+                        <c:extLst>
+                            <c:ext uri="{CE6537A1-D6FC-4f65-9D91-7224C49458BB}"
+                                   xmlns:c15="http://schemas.microsoft.com/office/drawing/2012/chart">
+                                <c15:showLeaderLines val="1"/>
+                            </c:ext>
+                        </c:extLst>
+                    </c:dLbls>
+                    <c:cat>
+                        <c:strRef>
+                            <c:f>categories</c:f>
+                            <c:strCache>
+                                <c:ptCount val="12"/>
+                                <c:pt idx="0">
+                                    <c:v>1月</c:v>
+                                </c:pt>
+                                <c:pt idx="1">
+                                    <c:v>2月</c:v>
+                                </c:pt>
+                                <c:pt idx="2">
+                                    <c:v>3月</c:v>
+                                </c:pt>
+                                <c:pt idx="3">
+                                    <c:v>4月</c:v>
+                                </c:pt>
+                                <c:pt idx="4">
+                                    <c:v>5月</c:v>
+                                </c:pt>
+                                <c:pt idx="5">
+                                    <c:v>6月</c:v>
+                                </c:pt>
+                                <c:pt idx="6">
+                                    <c:v>7月</c:v>
+                                </c:pt>
+                                <c:pt idx="7">
+                                    <c:v>8月</c:v>
+                                </c:pt>
+                                <c:pt idx="8">
+                                    <c:v>9月</c:v>
+                                </c:pt>
+                                <c:pt idx="9">
+                                    <c:v>10月</c:v>
+                                </c:pt>
+                                <c:pt idx="10">
+                                    <c:v>11月</c:v>
+                                </c:pt>
+                                <c:pt idx="11">
+                                    <c:v>12月</c:v>
+                                </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:cat>
+                    <c:val>
+                        <c:numRef>
+                            <c:f>0</c:f>
+                            <c:numCache>
+                                <c:formatCode>#,##0.00</c:formatCode>
+                                <c:ptCount val="12"/>
+                                                                    <c:pt idx="0">
+                                        <c:v>41.19</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>52.36</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>33.17</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>21.98</c:v>
+                                    </c:pt>
+                            </c:numCache>
+                        </c:numRef>
+                    </c:val>
+                    <c:smooth val="0"/>
+                    <c:extLst>
+                        <c:ext uri="{C3380CC4-5D6E-409C-BE32-E72D297353CC}"
+                               xmlns:c16="http://schemas.microsoft.com/office/drawing/2014/chart">
+                            <c16:uniqueId val="{00000000-C4BB-4702-BC7A-19503C6C333F}"/>
+                        </c:ext>
+                    </c:extLst>
+                </c:ser>
+                <c:dLbls>
+                    <c:showLegendKey val="0"/>
+                    <c:showVal val="0"/>
+                    <c:showCatName val="0"/>
+                    <c:showSerName val="0"/>
+                    <c:showPercent val="0"/>
+                    <c:showBubbleSize val="0"/>
+                </c:dLbls>
+                <c:hiLowLines>
+                    <c:spPr>
+                        <a:ln w="0">
+                            <a:noFill/>
+                        </a:ln>
+                    </c:spPr>
+                </c:hiLowLines>
+                <c:smooth val="0"/>
+                <c:axId val="30812407"/>
+                <c:axId val="43232623"/>
+            </c:lineChart>
+            <c:catAx>
+                <c:axId val="30812407"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="0"/>
+                <c:axPos val="b"/>
+                <c:numFmt formatCode="General" sourceLinked="0"/>
+                <c:majorTickMark val="none"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:spPr>
+                    <a:ln w="9360">
+                        <a:solidFill>
+                            <a:srgbClr val="D9D9D9"/>
+                        </a:solidFill>
+                        <a:round/>
+                    </a:ln>
+                </c:spPr>
+                <c:txPr>
+                    <a:bodyPr/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:endParaRPr lang="zh-CN"/>
+                    </a:p>
+                </c:txPr>
+                <c:crossAx val="43232623"/>
+                <c:crosses val="autoZero"/>
+                <c:auto val="1"/>
+                <c:lblAlgn val="ctr"/>
+                <c:lblOffset val="100"/>
+                <c:noMultiLvlLbl val="0"/>
+            </c:catAx>
+            <c:valAx>
+                <c:axId val="43232623"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="1"/>
+                <c:axPos val="l"/>
+                <c:numFmt formatCode="General" sourceLinked="1"/>
+                <c:majorTickMark val="none"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:crossAx val="30812407"/>
+                <c:crosses val="autoZero"/>
+                <c:crossBetween val="between"/>
+            </c:valAx>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:plotArea>
+        <c:plotVisOnly val="1"/>
+        <c:dispBlanksAs val="gap"/>
+        <c:showDLblsOverMax val="1"/>
+    </c:chart>
+    <c:spPr>
+        <a:solidFill>
+            <a:srgbClr val="FFFFFF"/>
+        </a:solidFill>
+        <a:ln w="9360">
+            <a:solidFill>
+                <a:srgbClr val="D9D9D9"/>
+            </a:solidFill>
+            <a:round/>
+        </a:ln>
+    </c:spPr>
+</c:chartSpace>

+ 314 - 0
templates/car/report/docx/word/charts/chart5.xml

@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
+              xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
+              xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
+              xmlns:c16r2="http://schemas.microsoft.com/office/drawing/2015/06/chart">
+    <c:date1904 val="1"/>
+    <c:lang val="zh-CN"/>
+    <c:roundedCorners val="0"/>
+    <c:style val="2"/>
+    <c:chart>
+        <c:title>
+            <c:tx>
+                <c:rich>
+                    <a:bodyPr rot="0"/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:r>
+                            <a:rPr lang="zh-CN" altLang="en-US" sz="1400" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:rPr>
+                            <a:t>自有车辆单车维修费(元)</a:t>
+                        </a:r>
+                    </a:p>
+                </c:rich>
+            </c:tx>
+            <c:overlay val="0"/>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:title>
+        <c:autoTitleDeleted val="0"/>
+        <c:plotArea>
+            <c:layout/>
+            <c:barChart>
+                <c:barDir val="col"/>
+                <c:grouping val="clustered"/>
+                <c:varyColors val="0"/>
+                <c:ser>
+                    <c:idx val="0"/>
+                    <c:order val="0"/>
+                    <c:tx>
+                        <c:strRef>
+                            <c:f>label 0</c:f>
+                            <c:strCache>
+                                <c:ptCount val="1"/>
+                                <c:pt idx="0">
+                                    <c:v>自有车辆单车维修费(元)</c:v>
+                                </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:tx>
+                    <c:spPr>
+                        <a:solidFill>
+                            <a:srgbClr val="4472C4"/>
+                        </a:solidFill>
+                        <a:ln w="0">
+                            <a:noFill/>
+                        </a:ln>
+                    </c:spPr>
+                    <c:invertIfNegative val="0"/>
+                    <c:dLbls>
+                        <c:numFmt formatCode="#,##0" sourceLinked="0"/>
+                        <c:spPr>
+                            <a:noFill/>
+                            <a:ln>
+                                <a:noFill/>
+                            </a:ln>
+                            <a:effectLst/>
+                        </c:spPr>
+                        <c:txPr>
+                            <a:bodyPr wrap="square"/>
+                            <a:lstStyle/>
+                            <a:p>
+                                <a:pPr>
+                                    <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                        <a:solidFill>
+                                            <a:srgbClr val="404040"/>
+                                        </a:solidFill>
+                                        <a:latin typeface="等线"/>
+                                    </a:defRPr>
+                                </a:pPr>
+                                <a:endParaRPr lang="zh-CN"/>
+                            </a:p>
+                        </c:txPr>
+                        <c:dLblPos val="outEnd"/>
+                        <c:showLegendKey val="0"/>
+                        <c:showVal val="1"/>
+                        <c:showCatName val="0"/>
+                        <c:showSerName val="0"/>
+                        <c:showPercent val="0"/>
+                        <c:showBubbleSize val="1"/>
+                        <c:separator>;</c:separator>
+                        <c:showLeaderLines val="0"/>
+                        <c:extLst>
+                            <c:ext uri="{CE6537A1-D6FC-4f65-9D91-7224C49458BB}"
+                                   xmlns:c15="http://schemas.microsoft.com/office/drawing/2012/chart">
+                                <c15:showLeaderLines val="1"/>
+                            </c:ext>
+                        </c:extLst>
+                    </c:dLbls>
+                    <c:cat>
+                        <c:strRef>
+                            <c:f>categories</c:f>
+                            <c:strCache>
+                                <c:ptCount val="14"/>
+                                    <c:pt idx="0">
+                                        <c:v>雄安</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>保定</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>邯郸</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>邢台</c:v>
+                                    </c:pt>
+                                    <c:pt idx="4">
+                                        <c:v>承德</c:v>
+                                    </c:pt>
+                                    <c:pt idx="5">
+                                        <c:v>唐山</c:v>
+                                    </c:pt>
+                                    <c:pt idx="6">
+                                        <c:v>沧州</c:v>
+                                    </c:pt>
+                                    <c:pt idx="7">
+                                        <c:v>平均</c:v>
+                                    </c:pt>
+                                    <c:pt idx="8">
+                                        <c:v>张家口</c:v>
+                                    </c:pt>
+                                    <c:pt idx="9">
+                                        <c:v>秦皇岛</c:v>
+                                    </c:pt>
+                                    <c:pt idx="10">
+                                        <c:v>机动局</c:v>
+                                    </c:pt>
+                                    <c:pt idx="11">
+                                        <c:v>石家庄</c:v>
+                                    </c:pt>
+                                    <c:pt idx="12">
+                                        <c:v>廊坊</c:v>
+                                    </c:pt>
+                                    <c:pt idx="13">
+                                        <c:v>衡水</c:v>
+                                    </c:pt>
+                            </c:strCache>
+                        </c:strRef>
+                    </c:cat>
+                    <c:val>
+                        <c:numRef>
+                            <c:f>0</c:f>
+                            <c:numCache>
+                                <c:formatCode>#,##0</c:formatCode>
+                                <c:ptCount val="14"/>
+                                    <c:pt idx="0">
+                                        <c:v>0</c:v>
+                                    </c:pt>
+                                    <c:pt idx="1">
+                                        <c:v>3</c:v>
+                                    </c:pt>
+                                    <c:pt idx="2">
+                                        <c:v>32</c:v>
+                                    </c:pt>
+                                    <c:pt idx="3">
+                                        <c:v>36</c:v>
+                                    </c:pt>
+                                    <c:pt idx="4">
+                                        <c:v>254</c:v>
+                                    </c:pt>
+                                    <c:pt idx="5">
+                                        <c:v>322</c:v>
+                                    </c:pt>
+                                    <c:pt idx="6">
+                                        <c:v>348</c:v>
+                                    </c:pt>
+                                    <c:pt idx="7">
+                                        <c:v>386</c:v>
+                                    </c:pt>
+                                    <c:pt idx="8">
+                                        <c:v>437</c:v>
+                                    </c:pt>
+                                    <c:pt idx="9">
+                                        <c:v>505</c:v>
+                                    </c:pt>
+                                    <c:pt idx="10">
+                                        <c:v>539</c:v>
+                                    </c:pt>
+                                    <c:pt idx="11">
+                                        <c:v>540</c:v>
+                                    </c:pt>
+                                    <c:pt idx="12">
+                                        <c:v>988</c:v>
+                                    </c:pt>
+                                    <c:pt idx="13">
+                                        <c:v>1011</c:v>
+                                    </c:pt>
+                            </c:numCache>
+                        </c:numRef>
+                    </c:val>
+                    <c:extLst>
+                        <c:ext uri="{C3380CC4-5D6E-409C-BE32-E72D297353CC}"
+                               xmlns:c16="http://schemas.microsoft.com/office/drawing/2014/chart">
+                            <c16:uniqueId val="{00000000-DD12-468E-92B4-2CF460CCC051}"/>
+                        </c:ext>
+                    </c:extLst>
+                </c:ser>
+                <c:dLbls>
+                    <c:showLegendKey val="0"/>
+                    <c:showVal val="0"/>
+                    <c:showCatName val="0"/>
+                    <c:showSerName val="0"/>
+                    <c:showPercent val="0"/>
+                    <c:showBubbleSize val="0"/>
+                </c:dLbls>
+                <c:gapWidth val="219"/>
+                <c:overlap val="-27"/>
+                <c:axId val="36727953"/>
+                <c:axId val="37543817"/>
+            </c:barChart>
+            <c:catAx>
+                <c:axId val="36727953"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="0"/>
+                <c:axPos val="b"/>
+                <c:numFmt formatCode="General" sourceLinked="0"/>
+                <c:majorTickMark val="none"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:spPr>
+                    <a:ln w="9360">
+                        <a:solidFill>
+                            <a:srgbClr val="D9D9D9"/>
+                        </a:solidFill>
+                        <a:round/>
+                    </a:ln>
+                </c:spPr>
+                <c:txPr>
+                    <a:bodyPr/>
+                    <a:lstStyle/>
+                    <a:p>
+                        <a:pPr>
+                            <a:defRPr sz="900" b="0" strike="noStrike" spc="-1">
+                                <a:solidFill>
+                                    <a:srgbClr val="595959"/>
+                                </a:solidFill>
+                                <a:latin typeface="等线"/>
+                            </a:defRPr>
+                        </a:pPr>
+                        <a:endParaRPr lang="zh-CN"/>
+                    </a:p>
+                </c:txPr>
+                <c:crossAx val="37543817"/>
+                <c:crosses val="autoZero"/>
+                <c:auto val="1"/>
+                <c:lblAlgn val="ctr"/>
+                <c:lblOffset val="100"/>
+                <c:noMultiLvlLbl val="0"/>
+            </c:catAx>
+            <c:valAx>
+                <c:axId val="37543817"/>
+                <c:scaling>
+                    <c:orientation val="minMax"/>
+                </c:scaling>
+                <c:delete val="1"/>
+                <c:axPos val="l"/>
+                <c:numFmt formatCode="General" sourceLinked="1"/>
+                <c:majorTickMark val="none"/>
+                <c:minorTickMark val="none"/>
+                <c:tickLblPos val="nextTo"/>
+                <c:crossAx val="36727953"/>
+                <c:crosses val="autoZero"/>
+                <c:crossBetween val="between"/>
+            </c:valAx>
+            <c:spPr>
+                <a:noFill/>
+                <a:ln w="0">
+                    <a:noFill/>
+                </a:ln>
+            </c:spPr>
+        </c:plotArea>
+        <c:plotVisOnly val="1"/>
+        <c:dispBlanksAs val="gap"/>
+        <c:showDLblsOverMax val="1"/>
+    </c:chart>
+    <c:spPr>
+        <a:solidFill>
+            <a:srgbClr val="FFFFFF"/>
+        </a:solidFill>
+        <a:ln w="9360">
+            <a:solidFill>
+                <a:srgbClr val="D9D9D9"/>
+            </a:solidFill>
+            <a:round/>
+        </a:ln>
+    </c:spPr>
+</c:chartSpace>

Diff do ficheiro suprimidas por serem muito extensas
+ 7099 - 0
templates/car/report/docx/word/document.xml


BIN
templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet.xlsx


BIN
templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet1.xlsx


BIN
templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet2.xlsx


BIN
templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet3.xlsx


BIN
templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet4.xlsx


BIN
templates/car/report/docx/word/embeddings/Microsoft_Excel_Worksheet5.xlsx


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
templates/car/report/docx/word/fontTable.xml


BIN
templates/car/report/docx/word/media/image1.png


BIN
templates/car/report/docx/word/media/image2.emf


BIN
templates/car/report/docx/word/media/image3.emf


BIN
templates/car/report/docx/word/media/image4.emf


BIN
templates/car/report/docx/word/media/image5.emf


BIN
templates/car/report/docx/word/media/image6.emf


BIN
templates/car/report/docx/word/media/image7.emf


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
templates/car/report/docx/word/settings.xml


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
templates/car/report/docx/word/styles.xml


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
templates/car/report/docx/word/theme/theme1.xml


+ 2 - 0
templates/car/report/docx/word/webSettings.xml

@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<w:webSettings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16du"/>

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff