设计一款可扩展和基于windows系统的一键处理表格小工具思路

news2025/1/11 12:35:47

原创/朱季谦

image

设计一款可扩展和基于windows系统的一键处理表格小工具思路

日常开发当中,业务人员经常会遇到一些重复性整理表格的事情,这时候,就可以通过一些方式进行自动化程序处理,提高工作(摸鱼)效率。

例如,业务人员有这样需要,日常需要手工整理以下原始xlsx表格数据,这些数据格式都是固定死,他们需要去除【手机号】这一列,然后在第一行增加一个表头标题【审计结果表】,同时需要将【日期】格式统一整理成yyyy-mm-dd格式的,最后需要在日期列前面增加一列【是否合格】,统一设置值为1。

image

整理后的表格如下:

image

注意,真实需求会比以上需求更加复杂,这里只是以一个比较简单的需求展开演示,来设计一个可一键傻瓜式自动化整理日常表格的工具。

工具的开发环境如下:

Java,Bat,需要依赖处理表格的poi的maven依赖。

一、创建一个maven工程,pom.xml依赖如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>auto-put-file</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven-clean-plugin.version>3.1.0</maven-clean-plugin.version>
        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
        <maven-dependency-plugin.version>3.1.2</maven-dependency-plugin.version>
        <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
        <maven-install-plugin.version>2.5.2</maven-install-plugin.version>
        <maven-jar-plugin.version>3.1.2</maven-jar-plugin.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.2.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>

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

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.2</version>
        </dependency>

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

        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>xdocreport</artifactId>
            <version>2.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>


    <build>
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>${maven-clean-plugin.version}</version>
                </plugin>

                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>${maven-deploy-plugin.version}</version>
                </plugin>


                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>${maven-install-plugin.version}</version>
                </plugin>

                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>${maven-jar-plugin.version}</version>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven-compiler-plugin.version}</version>
                    <configuration>
                        <encoding>UTF-8</encoding>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>3.1.1</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>com.put.AutoExcel</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>

    </build>
</project>

注意下, com.put.AutoExcel这一行需要填写你的main对应路径,如果路径不对的话,打成jar后,是无法通过java -jar xxx.jar运行的。

我在项目里依赖的4.1.2版本的org.apache.poi依赖包,最开始使用的是4.1.0版本的,但发现里面有一个很大的bug,就是使用XSSFSheet中处理指定行数据下移的方法sheet.shiftRows(0,sheet.getLastRowNum(),1,true,false)时,会发现指定下移位置之后的数据,都被删除完了,导致下移后的表格都成了一片空白。后来,我改成了4.1.2版本,才没有这个问题,但是,注意了,4.1.2版本依旧存在一个bug,那便是将第二列数据通过sheet.shiftColumns(1,sheet.getRow(0).getLastCellNum(),-1)左移覆盖掉第一列时,会出现以下异常:

Exception in thread "Thread-0" java.lang.IndexOutOfBoundsException
	at org.apache.xmlbeans.impl.store.Xobj.removeElement(Xobj.java:2206)
	at org.apache.xmlbeans.impl.store.Xobj.remove_element(Xobj.java:2236)
	at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl.removeC(Unknown Source)
	at org.apache.poi.xssf.usermodel.XSSFRow.fixupCTCells(XSSFRow.java:612)
	at org.apache.poi.xssf.usermodel.XSSFRow.onDocumentWrite(XSSFRow.java:582)
	at org.apache.poi.xssf.usermodel.XSSFSheet.write(XSSFSheet.java:3640)
	at org.apache.poi.xssf.usermodel.XSSFSheet.commit(XSSFSheet.java:3585)
	at org.apache.poi.ooxml.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:490)
	at org.apache.poi.ooxml.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:495)
	at org.apache.poi.ooxml.POIXMLDocument.write(POIXMLDocument.java:236)
	at com.put.service.impl.ConToImageServiceImpl.export(ConToImageServiceImpl.java:64)
	at com.put.AutoExcel.lambda$main$0(AutoExcel.java:26)
	at java.lang.Thread.run(Thread.java:745)

查看一些资料得知,即使到了5.x版本,该bug一直没有完全修复,只能通过先删除第一列后,再将第二列之后的数据往左移一列的方式,曲线解决这个反向移动问题。

二、基于Java SPI设计一套可便于后期扩展的接口实现

image

我在工程里使用到了Java SPI的服务发现机制,便于后期如果有需要进行工具处理新功能扩展,只需要增加一个实现类,放到com.put.service.DisposeService文件目录里,这样,后期就不需要改动原有工具的代码了。

1、先创建一个接口DisposeService:

package com.put.service;

/**
 * TODO
 *
 * @author zhujiqian
 * @date 2023/3/16 09:38
 **/
public interface DisposeService {
    public void export(String sourceFile, String sourceFileName);
}

这里的sourceFile是包括文件后缀的字符串名,例如:“测试表格文件.xlsx”,用来读取文件内容。

sourceFileName是没有的文件后缀的字符串名,例如:“测试表格文件”,用来创建用于存放已经整理的文件的目录。

2、创建一个实现类DisposeServiceImpl:

package com.put.service.impl;

import com.put.service.DisposeService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import static com.put.utils.DateUtil.timeFormat;

/**
 * TODO
 *
 * @author zhujiqian
 * @date 2023/3/16 16:40
 **/
public class DisposeServiceImpl implements DisposeService {
    @Override
    public void export(String sourceFile,String sourceFileName) {
        System.out.println("开始整理"+sourceFileName+"文件");
        try {
            FileInputStream file = new FileInputStream(sourceFile);
            XSSFWorkbook workbook = new XSSFWorkbook(file);
            //处理第一个sheet,若需要处理多个sheet,可以自行扩展
            XSSFSheet sheet = workbook.getSheetAt(0);
            //移除表格第一列
            removeCell(sheet,0);
            //移除表格第一列后,接着将原先第二列的数据往左边移动,即变成了第一列
            sheet.shiftColumns(1,sheet.getRow(0).getLastCellNum(),-1);
            //表格最后一列往右移动一格
            sheet.shiftColumns(sheet.getRow(0).getLastCellNum()-1,sheet.getRow(0).getLastCellNum(),1);
            //在倒数第二列地方新增一个表头标题
            sheet.getRow(0).createCell(sheet.getRow(0).getLastCellNum() - 2).setCellValue("是否合格");

            for(int i = 1; i<= sheet.getLastRowNum(); i++){
                if(sheet.getRow(i) == null){
                    continue;
                }

            //单元格为空,则继续同一列的下一个单元格
            if(sheet.getRow(i).getCell(sheet.getRow(i).getLastCellNum()-1) == null ){
                continue;
            }
            //调整最右边的申请时间数据
            int cellNum = sheet.getRow(i).getLastCellNum();
            XSSFCell cell = sheet.getRow(i).getCell(cellNum- 1);
            cell.setCellType(CellType.STRING);
            cell.setCellValue(timeFormat(cell.toString()));
            //对倒数第二列标题为【是否合格】的列从第二行开始赋值为1
            sheet.getRow(i).createCell(cellNum - 2).setCellValue(1);
        }

            //数据下移一行,空出第一行,设置新表头标题
            sheet.shiftRows(0,sheet.getLastRowNum(),1,true,false);
            XSSFRow rows = sheet.createRow(0);
            rows.createCell(0).setCellValue("审计结果表");


            FileOutputStream outFile =new FileOutputStream(System.getProperty("user.dir")+"//整理结果//"+sourceFileName+"//"+"处理完的表格.xlsx");

            //写入到新文件里
            workbook.write(outFile);
            file.close();
            outFile.flush();
            outFile.close();
            System.out.println("整理完成");
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    public static void removeCell(XSSFSheet sheet, int index){
         for (Row row : sheet) {
             Cell cell = row.getCell(index);
             if (cell != null) {
                 row.removeCell(cell);
             }
         }
    }
}

这个方法主要分成以下几个步骤:

1、读取源文件内容,创建一个可读取表格的XSSFWorkbook对象,并通过workbook.getSheetAt(0)获取第一个sheet表格;

FileInputStream file = new FileInputStream(sourceFile);
XSSFWorkbook workbook = new XSSFWorkbook(file);
//处理第一个sheet,若需要处理多个sheet,可以自行扩展
XSSFSheet sheet = workbook.getSheetAt(0);

2、删除第一列数据,然后将第二列开始到最后一列的数据往左移动一列,即原本的第二列变成第一列,第三列变成第二列,依次移动;

//移除表格第一列
removeCell(sheet,0);
//移除表格第一列后,接着将原先第二列的数据往左边移动,即变成了第一列
sheet.shiftColumns(1,sheet.getRow(0).getLastCellNum(),-1);

removeCell(sheet,0)代码如下:

public static void removeCell(XSSFSheet sheet, int index){
     for (Row row : sheet) {
         Cell cell = row.getCell(index);
         if (cell != null) {
             row.removeCell(cell);
         }
     }
}

注意一点,前面有提到,直接使用sheet.shiftColumns(1,sheet.getRow(0).getLastCellNum(),-1)对第二列数据往左移动会报错,故而需要先删除第一列,再作迁移。

3、表格最后一列往右移动一格,然后在倒数第二列新增一个表头标题【是否合格】;

//表格最后一列往右移动一格
sheet.shiftColumns(sheet.getRow(0).getLastCellNum()-1,sheet.getRow(0).getLastCellNum(),1);
//在倒数第二列地方新增一个表头标题
sheet.getRow(0).createCell(sheet.getRow(0).getLastCellNum() - 2).setCellValue("是否合格");

4、调整最右边的申请时间数据,统一改成“yyyy-mm-dd”格式,同时对倒数第二列标题为【是否合格】的列从第二行开始赋值为1;

for(int i = 1; i<= sheet.getLastRowNum(); i++){
    if(sheet.getRow(i) == null){
        continue;
    }

    //单元格为空,则继续同一列的下一个单元格
    if(sheet.getRow(i).getCell(sheet.getRow(i).getLastCellNum()-1) == null ){
        continue;
    }
    //调整最右边的申请时间数据
    int cellNum = sheet.getRow(i).getLastCellNum();
    XSSFCell cell = sheet.getRow(i).getCell(cellNum- 1);
    cell.setCellType(CellType.STRING);
    cell.setCellValue(timeFormat(cell.toString()));
    //对倒数第二列标题为【是否合格】的列从第二行开始赋值为1
    sheet.getRow(i).createCell(cellNum - 2).setCellValue(1);
}

5、所有数据下移一行,空出第一行设置新表头标题;

//数据下移一行,空出第一行,设置新表头标题
sheet.shiftRows(0,sheet.getLastRowNum(),1,true,false);
XSSFRow rows = sheet.createRow(0);
rows.createCell(0).setCellValue("审计结果表");

7、写入到指定目录的新文件,关闭读取;

FileOutputStream outFile =new FileOutputStream(System.getProperty("user.dir")+"//整理结果//"+sourceFileName+"//"+"处理完的表格.xlsx");
//写入到新文件里
workbook.write(outFile);
file.close();
outFile.flush();
outFile.close();
System.out.println("整理完成");

其中,处理时间的方法代码如下,可支持对yyyy/mm/dd hh:mm:ss、yyyy/m/d h:mm:ss、yyyy/m/dd h:mm:ss、yyyymmdd、yyyy/mm/dd、yyyy/m/d、yyyy/m/dd、excel格式这些格式统一处理成“yyyy-mm-dd”:

public static String timeFormat(String date) {
        if ("".equals(date) || date == null) return "时间为空";
        if (date.length() < 5) return "时间格式错误";
        if (date.charAt(4) == '-') return date;
        String dateFormat = "";
        switch (date.length()){
            case 19:
            case 10:
                dateFormat = date.substring(0, 4) + "-" + date.substring(5, 7) + "-" + date.substring(8, 10);
                break;
            case 9:
                if (date.charAt(4) != '/' )break;
            case 17:
                dateFormat = date.substring(0, 4) + "-" + date.charAt(5) + "-" + date.substring(7, 9);
                break;

            case 8:
                if (date.charAt(4) != '/' ){
                    dateFormat = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6);
                    break;
                }
            case 16:
                dateFormat = date.substring(0, 4) + "-" + date.charAt(5) + "-" + date.charAt(7);
                break;
            case 5:
                return numberToDate(date);
            default:
                return "时间格式错误";
        }
        return dateFormat;
    }


public static String numberToDate(String number){
        Calendar calendar = new GregorianCalendar(1900,0,-1);
        Date date = DateUtils.addDays(calendar.getTime(),Integer.parseInt(number));
        //对日期格式化操作
        return new SimpleDateFormat("yyyy-MM-dd").format(date);
    }

因为是使用到Java SPI机制,故而需要在resource目录下创建一个META_INF.services目录,目录下创建一个与接口路径同名的文件:com.put.service.DisposeService。该文件里存放需要调用的DisposeService接口的实现类,然后就可以自动实现接口实现类的自动调用处理了。同理,后期若不需要调用某个实现类的方法了,只需要将该文件里的指定实现类路径去掉即可。

com.put.service.impl.DisposeServiceImpl

三、最后,新增一个main启动

public class AutoExcel {



    public static void main(String[] argv) {
        start();
    }


    public static void start(){
        //获取Java项目所在目录
        File file = new File(System.getProperty("user.dir"));
        for (File f : file.listFiles()){
            if (!f.isDirectory() && f.getName().contains(".xlsx")){
                String sourceFile = f.getName();
                String sourceFileName = sourceFile.substring(0,sourceFile.lastIndexOf("."));
                if (StringUtils.isAnyBlank(sourceFile,sourceFileName))return;
                //创建文件目录
                createDirectory(sourceFileName);
                //基于SPI机制自动调用实现类来实现文件处理
                execute(sourceFile,sourceFileName);
            }
        }
    }

    public static void createDirectory(String sourceName){
        File file = new File(System.getProperty("user.dir") + "//整理结果//" + sourceName);
        if (!file.exists()){
            file.mkdirs();
        }
    }

    public static void execute(String sourceFile, String sourceName){
        ServiceLoader<DisposeService> serviceLoader = ServiceLoader.load(DisposeService.class);
        Iterator<DisposeService> serviceIterator = serviceLoader.iterator();
        while (serviceIterator.hasNext()){
            DisposeService service = serviceIterator.next();
            if (service == null)return;
            new Thread(()->{
                service.export(sourceFile,sourceName);
            }).start();
        }
    }
}

基于以上代码来梳理说明一下流程:

1、获取Java项目所在的文件路径,然后获取该路径的.xlsx表格文件名,若是存在多个.xlsx表格文件,可以同时批量处理。

File file = new File(System.getProperty("user.dir"));
for (File f : file.listFiles()){
    if (!f.isDirectory() && f.getName().contains(".xlsx")){
        String sourceFile = f.getName();
        String sourceFileName = sourceFile.substring(0,sourceFile.lastIndexOf("."));
        if (StringUtils.isAnyBlank(sourceFile,sourceFileName))return;
        ......
    }
}

2、创建处理好的表格统一存放目录,路径名为,当前目录//整理结果//文件名同名文件夹//

public static void createDirectory(String sourceName){
    File file = new File(System.getProperty("user.dir") + "//整理结果//" + sourceName);
    if (!file.exists()){
        file.mkdirs();
    }
}

例如,处理的文件名为“测试表格文件.xlsx”,那么创建的目录结构效果如下:

image

3、基于Java SPI机制,读取获取接口对应的com.put.service.DisposeService文件内容,然后反射得到文件里指定的实现类,循环执行各个实现类的方法:

public static void execute(String sourceFile, String sourceName){
    ServiceLoader<DisposeService> serviceLoader = ServiceLoader.load(DisposeService.class);
    Iterator<DisposeService> serviceIterator = serviceLoader.iterator();
    while (serviceIterator.hasNext()){
        DisposeService service = serviceIterator.next();
        if (service == null)return;
        new Thread(()->{
            service.export(sourceFile,sourceName);
        }).start();
    }
}

该方法里我用了多线程并发处理,因为各个文件的处理无任何依赖,若是大批量处理时,串行执行实在太慢,但多线程处理同时也会存在一个问题是,若大批量表格文件中每个文件数据量都很大的话,电脑内存太小的话,可能会出现内存溢出问题。

三、maven项目打成一个jar,然后编写一个可在windows运行的bat脚本。

image

拷贝最后一个auto-put-file-1.0-SNAPSHOT-jar-with-dependencies.jar到随意一个目录里,然后编写一个名字为start.bat脚本:

@echo off
java -jar auto-put-file-1.0-SNAPSHOT-jar-with-dependencies.jar

将start.bat和auto-put-file-1.0-SNAPSHOT-jar-with-dependencies.jar放同一个目录里,然后将需要处理的Excel文件放到该目录下,点击start.bat即可运行。

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

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

相关文章

TCP七层协议

物理层 中间的物理链接可以是光缆、电缆、双绞线、无线电波。中间传的是电信号&#xff0c;即010101...这些二进制位。 比特(bit)是二进制&#xff08;Binary Digit&#xff09;的简称&#xff0c;电脑所有的信息都是二进制的&#xff0c;就是0和1组成的。 数据链路层 早期…

为何Go爬虫依然远没有Python爬虫流行

编程语言有很多种&#xff0c;哪种编程适合爬虫具体还得因项目而异。就以我常用GO和Python语言交替来写爬虫一样&#xff0c;针对不同项目采用不同语言来写爬虫。至于python为什么相比go更受欢迎&#xff0c;我总结了下面几种原因。 Go语言和Python语言在爬虫开发上的流行度差…

【spring】bean的后处理器

目录 一、作用二、常见的bean后处理器2.1 AutowiredAnnotationBeanPostProcessor2.1.1 说明2.1.2 代码示例2.1.3 截图示例 2.2 CommonAnnotationBeanPostProcessor2.2.1 说明2.2.2 代码示例2.2.3 截图示例 2.3 ConfigurationPropertiesBindingPostProcessor2.3.1 说明2.3.2 代码…

vivado实现分析与收敛技巧3-面向非工程用户的智能设计运行建议

要使用智能设计运行功能特性 &#xff0c; 需要 Vivado 工程。这是因为需要进行运行管理。以下指示信息解释了创建综合后工程的最简单方法。这些信息适用于以下流程的用户&#xff1a; • 非工程实现运行 • 使用较低版本的 Vivado 或第三方综合工具进行综合 访问智能设计…

高压功率放大器的应用领域有哪些

高压功率放大器是一种特殊的电子设备&#xff0c;用于放大低电压信号到较高的功率水平。它在许多应用领域中发挥着重要作用。下面西安安泰将详细介绍高压功率放大器的几个常见应用领域。 声学领域&#xff1a;高压功率放大器在声学领域中广泛应用。例如&#xff0c;在音响系统和…

【SparkSQL】SparkSQL函数定义(重点:定义UDF函数、使用窗口函数)

【大家好&#xff0c;我是爱干饭的猿&#xff0c;本文重点介绍SparkSQL 定义UDF函数、SparkSQL 使用窗口函数。 后续会继续分享其他重要知识点总结&#xff0c;如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下吧】 上一篇文章&#xff1a;《【SparkSQL…

Windows 安装redis,设置开机自启动

Windows 安装redis,设置开机自启动 文章目录 Windows 安装redis,设置开机自启动下载, 解压到指定目录设置redis密码启动redis服务端停止redis服务端设置自启动 下载, 解压到指定目录 官网地址: https://redis.io/ 安装包下载地址: https://github.com/tporadowski/redis/relea…

VScode 插件 CodeGeex 使用教程

VScode 插件 CodeGeex 使用教程 不过在笔者看来&#xff0c;和国外的 Copilot 存在不小的差距&#xff0c;Copilot 是基于国外的大模型&#xff0c;能力比国内 AI 大模型要强&#xff0c;但要付费、还可能因为网络原因影响速度&#xff0c;所以国内的胜在免费&#xff08;不过…

每日一题:LeetCode-1089. 复写零

每日一题系列&#xff08;day 09&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

文心大模型3.5 VS ChatGPT3.5,谁更会写代码 ?

问题&#xff1a;请帮我写一段代码&#xff0c;SAP物料凭证创建接口的代码 &#xff1f; 文心大模型3.5&#xff1a;写了一段 python ChatGPT3.5 : 写的还可以啊&#xff0c;理解的很到位,而且用的是S/4新语法呀 &#xff01; DATA: lt_header TYPE TABLE OF bapi2017_gm_head_…

观《王牌对王牌:国宝回国》有感 —— AI绘画之古画修复对比图

一、前言 上周《王牌对王牌》节目的主题是《国宝回国》&#xff0c;而今天的AI绘画的灵感&#xff0c;就来源于这期节目。 下面这组图&#xff0c;左侧部分因时间的流逝而显现出褪色和损伤的痕迹&#xff0c;色彩变得暗淡&#xff0c;细节也因年代久远而变得模糊不清。 而右…

SA与NSA网络架构的区别

SA与NSA网络架构的区别 1. 三大运营商网络制式&#xff1a;2. 5G组网方式及业务特性3. NSA-3系列4. NSA—4系列5. NSA-7系列6. 5G SA网络架构7. 运营商策略 1. 三大运营商网络制式&#xff1a; 联通&#xff1a;3G(WCDMA)\4G(FDD-LTE/TD-LTE)\5G(SA/NSA)移动&#xff1a;2G(GS…

专注数据采集分析系统研发 做设备与MES系统中转站

数据采集是实现MES系统与设备对接的核心环节。通过采集设备产生的实时数据&#xff0c;将其传输给MES系统进行处理和分析。数据采集可以通过直接连接设备的传感器或者通过设备上安装的采集设备实现。采集的数据可以包括设备的运行状态、产量数据、测量数据、能耗数据等。通过数…

光伏电站卫星测绘的优缺点有哪些?

由于环境保护和能源安全的重要性日益凸显&#xff0c;光伏发电作为一种清洁、可再生、分布式的能源形式&#xff0c;已经成为全球能源领域的热门话题。 光伏电站&#xff0c;是指一种利用太阳光能、采用特殊材料诸如晶硅板、逆变器等电子元件组成的发电体系&#xff0c;与电网相…

管理Windows资产新方式:SSH协议

配置默认shell&#xff0c;需要管理员权限运行powershell执行下面命令&#xff1a; New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -F…

SpringBootWeb案例_03

Web后端开发_06 SpringBootWeb案例_03 登录认证 智能学习辅助系统登录时需要身份验证 1.登录功能 先实现简单的登录功能&#xff0c;在进一步优化。 1.1需求 若账户或密码不存在/密码不正确&#xff0c;则登录失败。 账户密码正确&#xff0c;则登录成功 1.2接口文档 …

Android Studio - 显示配置

1.修改 Code / Split / Design&#xff08;代码视图 & 效果视图&#xff09; 路径&#xff1a;Settings→Editor→Design Tools。 2.增加打开文件的数量及展示方式 路径&#xff1a;Settings→Editor→General→Editor Tabs。

BUUCTF [UTCTF2020]docx 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 密文&#xff1a; 下载附件&#xff0c;得到一个.docx文件。 解题思路&#xff1a; 1、打开文件&#xff0c;内容如下&#xff0c;没有flag。 使用010 Editor打开.docx文件&…

AdWords 广告字符的限制是多少?

谷歌已经发展到不仅仅是一个简单的网络搜索。谷歌已成为任何组织所希望的最好的广告网络之一&#xff0c;不断有全球观众来到它研究项目和便利设施、数据、新闻、解决方案等等。 手机的变化带来了数字广告形式的初步转变&#xff0c;随后学习算法的发展和接受也给Google AdWor…

Qt基础 QListWidget dragDrop拖拽操作

目录 1.重写 2.本身自带拖拽功能 关于QLisWidget的item拖拽操作,也可以某个控件拖拽思路 1.重写 重写相当于要重写这些事件函数 void mousePressEvent(QMouseEvent *event); //鼠标按下 void mouseMoveEvent(QMouseEvent *event); //鼠标移动 void dragEnterE…