三种读写传统xls格式文件开源库libxls、xlslib、BasicExcel的比较

news2025/6/7 5:57:20

最近准备读写传统xls格式文件,而不是较新的xlsx,询问DeepSeek有哪些开源库,他给出了如下的简介和建议,还给出了相应链接,不过有的链接已失效。最后还不忘提醒,现在该用xlsx格式了。

以下是几个可以处理传统 .xls (Excel 97-2003) 格式的 C++ 库推荐:


1. libxls (推荐)

  • 特点
    • 纯C库,但可轻松用于C++项目
    • 轻量级,只读操作
    • 专门解析二进制.xls格式
  • 安装:
    # Ubuntu
    sudo apt-get install libxls-dev
    
  • 示例代码:
    #include <xls.h>
    
    void read_xls(const char* filename) {
        xlsWorkBook* pWB = xls_open(filename, "UTF-8");
        xlsWorkSheet* pWS = xls_getWorkSheet(pWB, 0);
        xls_parseWorkSheet(pWS);
        
        for (int row=0; row<pWS->rows.lastrow; row++) {
            for (int col=0; col<pWS->rows.lastcol; col++) {
                std::cout << pWS->rows.sheet[row].cells[col].str << "\t";
            }
            std::cout << std::endl;
        }
        
        xls_close_WS(pWS);
        xls_close_WB(pWB);
    }
    

2. BasicExcel

  • 特点
    • 纯头文件库
    • 支持读写操作
    • 仅支持基本功能(无图表、公式等)
  • GitHub: https://github.com/stephenquan/BasicExcel错误链接
  • 示例代码:
    #include "BasicExcel.hpp"
    
    void read_xls(const char* filename) {
        YExcel::BasicExcel excel;
        excel.Load(filename);
        
        YExcel::BasicExcelWorksheet* sheet = excel.GetWorksheet(0);
        for (size_t row=0; row<sheet->GetTotalRows(); row++) {
            for (size_t col=0; col<sheet->GetTotalCols(); col++) {
                YExcel::BasicExcelCell* cell = sheet->Cell(row, col);
                std::cout << cell->GetString() << "\t";
            }
            std::cout << std::endl;
        }
    }
    

3. xlslib (已停止维护)

  • 特点
    • 支持读写
    • 跨平台
  • 官网: http://xlslib.sourceforge.net
  • 示例:
    #include "xlslib.h"
    using namespace xlslib_core;
    
    void read_xls(const char* filename) {
        workbook wb;
        wb.Load(filename);
        
        worksheet* ws = wb.GetSheet(0);
        for (unsigned row=0; row<ws->LastRow(); row++) {
            for (unsigned col=0; col<ws->LastCol(); col++) {
                cell_t* cell = ws->FindCell(row, col);
                std::cout << cell->GetString() << "\t";
            }
            std::cout << std::endl;
        }
    }
    

4. Qt XLS (QXlsx)

  • 特点
    • 需要Qt框架
    • 支持读写
  • GitHub: https://github.com/QtExcel/QXlsx
  • 示例:
    #include <QXlsx/Workbook.h>
    
    void read_xls(const QString& filename) {
        QXlsx::Document xls(filename);
        for (int row=1; row<=xls.dimension().lastRow(); row++) {
            for (int col=1; col<=xls.dimension().lastColumn(); col++) {
                std::cout << xls.cellAt(row, col)->value().toString().toStdString() << "\t";
            }
            std::cout << std::endl;
        }
    }
    

选择建议:

  1. 只需读取 → 选libxls(最稳定)
  2. 需要简单读写 → 选BasicExcel
  3. 已使用Qt → 选QXlsx
  4. 需要完整功能 → 考虑用libreofficepoi的C++封装

注意:现代项目建议优先使用.xlsx格式(可用libxlsxwriterOpenXLSX库)。


以下是实际测试

版本

对我的小功能而言,Qt太重了,而且项目网页说“QXlsx is excel file(*.xlsx) reader/writer library”,也就是它其实不支持xls格式文件。所以下面比较前三种。

经过一番搜索,libxls原主页https://sourceforge.net/projects/libxls/,迁移到https://github.com/libxls/libxls了。最新的版本是libxls-1.6.3.tar.gz。

xlslib主页https://sourceforge.net/projects/xlslib/,还在,能正常下载。最新的版本是xlslib-package-2.5.0.zip。

BasicExcel我没找到软件网页,只找到作者Yap Chun Wei在2006年发表的一篇文章,但源代码链接已失效,于是又一通搜索,找到了存有该代码的的个人github项目,https://github.com/haorenhl007/BasicExcel,源码包。版本号是Version 1.14 (6 August 2006)。

libxls虽然也有apt安装和pkgs.org上可下载的软件包,但考虑公平比较,也顺便编译一遍源代码。

编译

libxls编译很简单,gnu软件的常规做法,解压、configure、make、make install即可。如果aarch64平台遇到编译器的问题,在安卓手机的termux+prooot环境中也能编译成功,然后这个so文件可拷贝到其他linux系统使用。
xlslib编译在x64平台相对顺利,参照libxls步骤即可。在aarch64平台编译会遇到问题,解决方法见前文。
BasicExcel无需单独编译,当然为了减少编译时间,也可以将它编译成动态链接库。方法如下:

g++ -std=c++14 -fPIC -c BasicExcel.cpp -o BasicExcel.o -O3
g++ -shared -o libbasic_excel.so BasicExcel.o

注意编译时加-O3参数,这样动态链接库的执行速度最快。调用它的主程序,因为没有大量实际操作,是否加-O3参数反而不重要了。

调用

将上述软件的头文件所在目录记录下来,在编译时用-I 参数提供。
将上述软件的so文件所在目录加入LIBRARY_PATH和LD_LIBRARY_PATH环境变量,前者是链接自己的程序时用,后者是运行时用。
如果用make install安装,则两者都在搜索路径中了。

功能

DeepSeek的简介已经写得很明白了,libxls只读、xlslib只写,功能全面,BasicExcel可读写,但只有基本功能。作者自己写的BasicExcel局限性如下:
它不支持格式化
它不支持公式
它不支持图表
它不支持Unicode UTF-32
它支持的东西如下:
读写数字(整数,实数)和字符串(ANSI,UTF16)
添加工作表
重命名工作表
删除工作表
获取工作表的名称
其实对我而言,这些功能也够用了。所以我的想法是,将它们做一个性能比较,最后各留下读性能和写性能最好的一个。

性能比较

我让DeepSeek编写了一个测试程序,提示词如下,

请把你列举的几个库用一个整合的main函数来测试读写(如果有)功能的计时,各种库写的示例xls文件,9个sheet,每个sheet分别是5列、10列、15列,分别是1百行,3百行,6百行,各种组合中都包括文本列、数字列、日期列。最后用BasicExcel输出一个存储比较结果,比较文件大小和读取或写入时间的excel表格

值得一提的是,它忘记了xlslib是只写的工具,所以还提交了测试读的代码,当然编译出错,现已删除。

#include <iostream>
#include <chrono>
#include <vector>
#include <string>
#include <iomanip>
#include <fstream>

// 测试配置
const std::vector<int> COLUMNS = {5,10};
const std::vector<int> ROWS = {8000};
const int SHEET_COUNT = 9;

// 测试数据生成
struct TestData {
    std::string text;
    double number;
    std::string date;
};

TestData generate_data(int row, int col) {
    return {
        "Text_" + std::to_string(row) + "_" + std::to_string(col),
        row * 0.1 + col,
        "2023-" + std::to_string(1 + col % 12) + "-" + std::to_string(1 + row % 28)
    };
}

// 测试结果存储
struct BenchmarkResult {
    std::string library;
    int columns;
    int rows;
    double write_time;
    double read_time;
    size_t file_size;
};

std::vector<BenchmarkResult> results;

// ----------------------------
// libxls 测试 (只读)
// ----------------------------
#ifdef USE_LIBXLS
#include <xls.h>
using namespace xls;
void test_libxls_read(const std::string& filename, int cols, int rows) {
    auto start = std::chrono::high_resolution_clock::now();
    
    xlsWorkBook* pWB = xls_open(filename.c_str(), "UTF-8");
    if (!pWB) {
        std::cerr << "Failed to open " << filename << std::endl;
        return;
    }

    for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {
        xlsWorkSheet* pWS = xls_getWorkSheet(pWB, sheet);
        xls_parseWorkSheet(pWS);
        
        // 简单验证数据
        if (pWS->rows.lastrow != rows || pWS->rows.lastcol != cols -1) {
            std::cerr << "Data mismatch in sheet " << sheet << pWS->rows.lastrow  <<" "<< rows   <<" "<< pWS->rows.lastcol  <<" "<< cols <<std::endl;
        }
        
        xls_close_WS(pWS);
    }

    xls_close_WB(pWB);
    
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = end - start;
    
    std::ifstream file(filename, std::ios::binary | std::ios::ate);
    size_t size = file.tellg();
    
    results.push_back({
        "libxls", cols, rows, 
        0.0, // 无写入测试
        elapsed.count(),
        size
    });
}
#endif

// ----------------------------
// BasicExcel 测试
// ----------------------------
#ifdef USE_BASICEXCEL
#include "BasicExcel.hpp"

void test_basic_excel(const std::string& filename, int cols, int rows) {
    // 写入测试
    auto write_start = std::chrono::high_resolution_clock::now();
    
    YExcel::BasicExcel excel;
    for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {
        YExcel::BasicExcelWorksheet* ws = excel.AddWorksheet(("Sheet" + std::to_string(sheet)).c_str());
        
        // 写入标题
        for (int col = 0; col < cols; ++col) {
            ws->Cell(0, col)->SetString(("Col_" + std::to_string(col)).c_str());
        }
        
        // 写入数据
        for (int row = 1; row <= rows; ++row) {
            TestData data = generate_data(row, cols);
            ws->Cell(row, 0)->SetString(data.text.c_str());
            ws->Cell(row, 1)->SetDouble(data.number);
            ws->Cell(row, 2)->SetString(data.date.c_str());
            
            // 填充剩余列
            for (int col = 3; col < cols; ++col) {
                ws->Cell(row, col)->SetString(("Extra_" + std::to_string(col)).c_str());
            }
        }
    }
    
    excel.SaveAs(filename.c_str());
    auto write_end = std::chrono::high_resolution_clock::now();
    
    // 读取测试
    auto read_start = std::chrono::high_resolution_clock::now();
    YExcel::BasicExcel excel2;
    if (!excel2.Load(filename.c_str())) {
        std::cerr << "Failed to load " << filename << std::endl;
        return;
    }
    
    for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {
        YExcel::BasicExcelWorksheet* ws = excel2.GetWorksheet(sheet);
        if (!ws) continue;
        
        // 简单验证数据
        if (ws->GetTotalRows() != rows + 1 || ws->GetTotalCols() != cols) {
            std::cerr << "Data mismatch in sheet " << sheet << ws->GetTotalRows()  <<" "<< rows + 1  <<" "<< ws->GetTotalCols()  <<" "<< cols <<std::endl;
        }
    }
    
    auto read_end = std::chrono::high_resolution_clock::now();
    
    std::chrono::duration<double> write_elapsed = write_end - write_start;
    std::chrono::duration<double> read_elapsed = read_end - read_start;
    
    std::ifstream file(filename, std::ios::binary | std::ios::ate);
    size_t size = file.tellg();
    
    results.push_back({
        "BasicExcel", cols, rows,
        write_elapsed.count(),
        read_elapsed.count(),
        size
    });
}
// ----------------------------
// 生成比较报告
// ----------------------------
void generate_report() {
    YExcel::BasicExcel report;
    YExcel::BasicExcelWorksheet* ws = report.AddWorksheet("Results");
    
    // 标题行
    ws->Cell(0, 0)->SetString("Library");
    ws->Cell(0, 1)->SetString("Columns");
    ws->Cell(0, 2)->SetString("Rows");
    ws->Cell(0, 3)->SetString("Write Time (s)");
    ws->Cell(0, 4)->SetString("Read Time (s)");
    ws->Cell(0, 5)->SetString("File Size (KB)");
    
    // 数据行
    for (size_t i = 0; i < results.size(); ++i) {
        const auto& res = results[i];
        int row = i + 1;
        
        ws->Cell(row, 0)->SetString(res.library.c_str());
        ws->Cell(row, 1)->SetDouble(res.columns);
        ws->Cell(row, 2)->SetDouble(res.rows);
        ws->Cell(row, 3)->SetDouble(res.write_time);
        ws->Cell(row, 4)->SetDouble(res.read_time);
        ws->Cell(row, 5)->SetDouble(res.file_size / 1024.0);
    }
    
    report.SaveAs("benchmark_results.xls");
    std::cout << "Benchmark report saved to benchmark_results.xls" << std::endl;
}
#endif

// ----------------------------
// xlslib 测试
// ----------------------------
#ifdef USE_XLSLIB
#include "xlslib.h"

void test_xlslib(const std::string& filename, int cols, int rows) {
    // 写入测试
    auto write_start = std::chrono::high_resolution_clock::now();
    
    xlslib_core::workbook wb;
    for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {
        xlslib_core::worksheet* ws = wb.sheet(("Sheet" + std::to_string(sheet)).c_str());
        
        // 写入标题
        for (int col = 0; col < cols; ++col) {
            ws->label(0, col, ("Col_" + std::to_string(col)).c_str());
        }
        
        // 写入数据
        for (int row = 1; row <= rows; ++row) {
            TestData data = generate_data(row, cols);
            ws->label(row, 0, data.text.c_str());
            ws->number(row, 1, data.number);
            ws->label(row, 2, data.date.c_str());
            
            // 填充剩余列
            for (int col = 3; col < cols; ++col) {
                ws->label(row, col, ("Extra_" + std::to_string(col)).c_str());
            }
        }
    }
    
    wb.Dump(filename.c_str());
    auto write_end = std::chrono::high_resolution_clock::now();
    
    // 读取测试
    auto read_start = std::chrono::high_resolution_clock::now();
/*  删除读取代码
*/    
    auto read_end = std::chrono::high_resolution_clock::now();
    
    std::chrono::duration<double> write_elapsed = write_end - write_start;
    std::chrono::duration<double> read_elapsed = read_end - read_start;
    
    std::ifstream file(filename, std::ios::binary | std::ios::ate);
    size_t size = file.tellg();
    
    results.push_back({
        "xlslib", cols, rows,
        write_elapsed.count(),
        read_elapsed.count(),
        size
    });
}
#endif



// ----------------------------
// 主函数
// ----------------------------
int main() {
    // 测试所有组合
    for (int cols : COLUMNS) {
        for (int rows : ROWS) {
            std::string base_name = "test_" + std::to_string(cols) + "x" + std::to_string(rows);
            
            #ifdef USE_BASICEXCEL
            test_basic_excel(base_name + "_basic.xls", cols, rows);
            #endif
            
            #ifdef USE_XLSLIB
            test_xlslib(base_name + "_xlslib.xls", cols, rows);
            #endif
            
            #ifdef USE_LIBXLS
            // 需要先用其他库生成文件
            test_libxls_read(base_name + "_basic.xls", cols, rows);
            #endif
        }
    }
    
    // 生成比较报告
    #ifdef USE_BASICEXCEL
    generate_report();
    #endif
    
    return 0;
}

将测试程序命名为excel_benchmark.cpp,编译脚本如下:

#1.只测试BasicExcel
#如果提前将BasicExcel编译成动态链接库
g++ -std=c++14 -c excel_benchmark.cpp -o excel_benchmark.o -DUSE_BASICEXCEL -O3
g++ -o excel_benchmark excel_benchmark.o  -L ./ -lbasic_excel
#如果一次性编译
g++ -o excel_benchmark excel_benchmark.cpp -DUSE_BASICEXCEL -O3

#2.只测试xlslib,因为数据量稍大,超过5000行,BasicExcel就执行出错
g++ -std=c++14 excel_benchmark.cpp -o excel_benchmark2 -DUSE_XLSLIB -I /par/xlslib/src -O3 -lxls

#3.测试BasicExcel+libxls
g++ -std=c++14 -c excel_benchmark.cpp -o excel_benchmark3.o -DUSE_BASICEXCEL -DUSE_LIBXLS -I /usr/local/include/xlslib -O3
g++ -o excel_benchmark3 excel_benchmark3.o  -L ./ -lbasic_excel -lxlsreader

#4.测试BasicExcel+xlslib
g++ -std=c++14 -c excel_benchmark.cpp -o excel_benchmark4.o -DUSE_BASICEXCEL -DUSE_XLSLIB -I /usr/local/include/xlslib -O3
g++ -o excel_benchmark4 excel_benchmark4.o  -L ./ -lbasic_excel -lxls

因为两个软件都定义了 ‘unsigned64_t’,编译冲突,没有测试xlslib+libxls的组合

各种规模的xls文件读写测试如下表所示,因为x64和arm配置不同不可比, 除了一开始显示BasicExcel过慢的写速度时跨平台比较外,其余均只测大家都正常的arm平台。

xlslib写2个8000行文件测试结果:

time ./excel_benchmark2

real	0m2.223s
user	0m2.116s
sys		0m0.076s

一个问题有待解决,BasicExcel在x64平台上的速度离奇地慢,1.3MB的文件写入用时13秒,约为aarch64上的百倍。更大的问题是,当文件稍大,比如10列5000行,就会发生内存分配错误,而代码中对这类错误并没有异常捕获机制,导致不能自动退出,而是耗尽系统资源。

所以结论就是, 各种库的兼容性都不错,都能跨平台使用。
xlslib在功能多很多的情况下,用时与BasicExcel相当或略慢,而且支持更大的文件,缺点是生成的文件较大。libxls的读速比BasicExcel快很多。

不同规模读写比较

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

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

相关文章

Nature子刊同款的宏基因组免疫球蛋白测序怎么做?

免疫球蛋白A&#xff08;IgA&#xff09;是人体肠道黏膜分泌的主要抗体&#xff0c;它在塑造肠道微生物群落和维持肠道稳态中起着关键作用&#xff0c;有研究发现缺乏IgA的患者更容易患自身免疫性疾病和感染性疾病。 目前用于研究IgA结合的主要技术是IgA-SEQ&#xff0c;结合了…

2025年牛客网秋招/社招高质量 Java 面试八股文整理

Java 面试 不论是校招还是社招都避免不了各种面试。笔试&#xff0c;如何去准备这些东西就显得格外重要。不论是笔试还是面试都是有章可循的。关键在于理解企业的需求&#xff0c;明确自己的定位&#xff0c;以及掌握一定的应试技巧。 笔试部分&#xff0c;通常是对基础知识、…

ADI的BF609双核DSP怎么做开发,我来说一说(五)LAN口测试

作者的话 ADI的双核DSP&#xff0c;第二颗是Blackfin系列的BF609&#xff0c;这颗DSP我用了很久&#xff0c;比较熟悉&#xff0c;且写过一些给新手的教程。 硬件准备 ADSP-BF609-CORE&#xff1a;ADI BF609开发板 产品链接&#xff1a;https://item.taobao.com/item.htm?…

行业赋能篇-2-能源行业安全运维升级

在能源行业&#xff0c;尤其是风电领域&#xff0c;运维作业往往面临“三高”挑战——高风险环境、高异构数据量&#xff09;、高合规要求。以海上风电场为例&#xff0c;传统运维依赖卫星电话沟通&#xff0c;数据记录碎片化&#xff0c;故障因信息传递延迟导致损失扩大。如何…

飞云智能波段主图+多空短线决策副图指标,组合操盘技术图文解说

如上图&#xff0c;组合指标&#xff1a;主图-飞云智能波段&#xff0c;红线上红色K线标记&#xff0c;波段做多.副图指标-多空短线决策&#xff0c;跟踪做短线&#xff0c;红柱做多&#xff0c;绿柱短线卖出或做空。 实战操作中&#xff0c;我们在主图红色线支撑上红色K线出现…

【51单片机】1. 基础点灯大师

1. 新建一个项目集一些基本操作 打开Keli软件&#xff0c;然后&#xff1a; 【Project】→【new μVision Project】→选择项目保存位置 建议文件名选一些通用的名字&#xff0c;如【Project】 左下角选择【Atmel】的【AT89C52】 弹出的【是否添加启动文件到文件夹下】&…

PC端直接打印功能(包括两张图片合并功能)

一、 效果图 二、demo代码 <template><div class"box"><divref"printContent"class"print-content"><div class"print-title">打印图片</div><imgclass"preview-image":src"merged…

Vue前端篇——项目目录结构介绍

&#x1f4d8; 前言 在正式开始学习 Vue 3 开发之前&#xff0c;了解并熟悉其项目目录结构是非常关键的第一步。一个清晰、规范的目录结构不仅有助于开发者高效地组织代码&#xff0c;还能显著提升项目的可读性和可维护性。 Vue 3 作为现代前端开发中广泛使用的主流框架之一&…

抽象工厂模式深度解析:从原理到与应用实战

作者简介 我是摘星&#xff0c;一名全栈开发者&#xff0c;专注 Java后端开发、AI工程化 与 云计算架构 领域&#xff0c;擅长Python技术栈。热衷于探索前沿技术&#xff0c;包括大模型应用、云原生解决方案及自动化工具开发。日常深耕技术实践&#xff0c;乐于分享实战经验与…

35.成功解决编写关于“江协科技”编写技巧第二期标志位积累的问题

江科大学长又发布了第二期的编写技巧&#xff01; 大家可以看看&#xff1a;https://space.bilibili.com/383400717 最后面给了一个未完成的任务&#xff1a; 这里我已经把这个问题给解决了&#xff01; 总代码放在资源里面&#xff0c;key.c放在文章最后面&#xff01;同时感…

Linux常用命令学习手册

Linux常用命令学习手册https://download.csdn.net/download/2401_87690752/90953550 《Linux常用命令学习手册》提供了一份实用的Linux操作指南&#xff0c;主要收录了系统管理和文件操作等基础命令。内容涵盖了目录切换、文件查看、权限设置等核心功能&#xff0c;适合Linux初…

Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(八):异步处理逻辑详解

在现代 Web 应用中&#xff0c;异步处理是实现流畅交互的核心技术。本文基于前几章实现的内容Tailwind CSS 实战&#xff1a;基于 Kooboo 构建 AI 对话框页面&#xff08;七&#xff09;&#xff1a;消息框交互功能添加-CSDN博客&#xff0c;深入解析 AI 对话框页面中异步逻辑的…

Unreal从入门到精通之 UE4 vs UE5 VR性能优化实战

文章目录 前言:准备工作UE4 vs UE5 性能对比引擎核心技术方案对比UE5 优化总结项目设置可伸缩性组设置VolumetricCloud最后前言: 最近在使用UE5制作VR项目 制作完后发现,我们的场景一直很卡顿,场景优化也做到了极致,但是帧率最高也才30+ 但是我们看到一个竞品,他的帧率竟…

COMSOL与MATLAB联合仿真人工智能的电学层析成像系统

关键词&#xff1a;MATLAB&#xff0c;电学层析成像&#xff0c;人工智能&#xff0c;图像重建&#xff0c;深度学习 一、引言 基于人工智能的电学层析成像系统是一种创新的检测技术&#xff0c;结合了电学层析成像技术与人工智能算法的优势。电学层析成像技术&#xff0c;简…

配置sudo免密却不生效的问题

如图&#xff0c;我配置了dhcp4这个账号sudo免密&#xff0c;但是执行sudo的时候还是要输密码。 查看dhcp的用户组&#xff0c;是配置了一个wheel组&#xff0c;而wheel组配置的是需要密码。 我们用dhcp4用户执行sudo -l 发下他匹配了两条命令策略&#xff0c;一个是免密一个…

大模型赋能:金融智能革命中的特征工程新纪元

一、AI进化论&#xff1a;从“判别”到“生成”的金融新战场 1.1 判别式AI的“痛点”与大模型的“破局” 想象这样一幅画面&#xff1a;银行风控模型像老式收音机&#xff0c;需要人工反复调试参数才能捕捉风险信号&#xff1b;而大模型则是智能调音台&#xff0c;能自动“听…

LHA9924芯片可代替AD7190,CS5530

LHA9924是一款高性能、单芯片模数转换器(ADC)。该器件包括一个低噪声可编程增益放大器(PGA)、Δ-Σ调制器和数字滤波器。该ADC支持两种运行模式&#xff0c;可在功耗与分辨率之间实现最佳平衡。双通道多路复用器可以选择外部信号测量和内部ADC测试信号。具有使输入电路短路来测…

短视频矩阵系统技术saas源头6年开发构架

在短视频内容爆发式增长的今天&#xff0c;短视频矩阵系统SAAS技术成为企业快速搭建视频平台的关键解决方案。本文将系统解析从技术源头到服务落地的全流程开发路径。 一、系统定义与技术基础 短视频矩阵系统是集视频上传、智能编辑、多端分享、高清播放于一体的综合性平台。其…

前端删除评论操作(局部更新数组)

​评论的删除是局部删除&#xff0c;把所点击的评论id号传递给后端&#xff0c;通知后端在数据库中删除数据&#xff0c;并且返回数据&#xff0c;但是在前端并不直接接收返回的数据&#xff0c;而是触发回调事件&#xff0c;在前端上进行删除评论&#xff0c;首先通过pId观察他…

在线OJ项目测试

一.项目简介 1.1项目背景 历史起源&#xff1a;最早的OJ系统&#xff08;如UVa、POJ&#xff09;是为国际大学生程序设计竞赛&#xff08;ICPC&#xff09;等赛事开发的&#xff0c;用于自动评判参赛者的代码正确性和效率。 需求场景&#xff1a;竞赛需要公平、高效的评分系统…