面向表格编程的力量——Butler介绍(翻译)

面向表格编程的力量

——Butler介绍<o:p></o:p>

原文:http://www.javaworld.com/javaworld/jw-10-2004/jw-1018-butler.html

摘要

自从面向对象和三层结构出现以后,企业应用设计者一直在尝试着隐藏数据库的具体结构。但是这样却增加了软件的复杂性,而且强迫开发者制造了除了底层以外的很多不必要的层次。这篇文章介绍了一个面向表格编程的库——Butler。Butler以JDBC为基础,包括很多具有数据感知能力的SWING组件,可以大大降低在企业客户端应用中书写底层GUI的压力。<o:p></o:p>

 <o:p></o:p>

当面向对象语言在企业应用中开始应用时,设计者遇到的是如何将关系模型转换成对象模型的压力。在面向对象模型里面,数据是被封装起来的。但关系模型则相反,数据是根本不需要隐藏的。由此很多设计者认为如果使用关系数据库不能被避免,他们将商业逻辑隐藏起来。

面向对象开发者的梦想就是有一个面向对象的数据库。但是这种数据库在市场竞争中无法获得足够的市场份额,而且很可能根本无法取代面向关系的数据库。最近,很多开发者,甚至面向对象论者,都承认关系数据库比面向对象数据要好。

尽管关系数据库有很多优势,但是很多主流的持续性框架(如EJB、JDO 、Hibernate)拒绝在关系数据库里面存储对象。所有的关系数据库都是由表、列、主键、外键、记录和查询等组成的。但是没有一个主流的产品具有符合这些实体的对象模型。

另一个可供选择的模型,面向表格编程模型,允许应用源代码知道真实的数据库结构,而不是将数据库结构隐藏在应用的映射层中。许多企业应用具有很多CRUD(create,read,update,delete)相关的逻辑,如果数据库结构不被隐藏的话,开发CRUD功能将会很简单。

有些人认为对象模型不必和数据库结构一致,这样即使在数据库结构改变的时候商业逻辑也不需要改变。但是这些人忽视了很多商业逻辑是在关系数据库schema上实现的,所以准确的说,改变数据库schema也将改变商业逻辑。

隐藏关系数据库真实结构的结果就是使用一个额外的抽象层。表、列和外键等必须映射到类、属性和关联等。在很多方面,需要为每个表做一个类,把每个列做成类的属性,用关联来代表外键。另外,SQL也被重新改造(如Hibernate查询语言HQL,JDO-QL,EJB-QL等)。为什么要增加这些额外的层次呢?这些层次提供了很少的特性,但是却增加了复杂性。

面向表格编程最大的优势就是提供了创建数据感知GUI组件的能力。如果你正在实现一个用来现实和(或)更新数据库中数据的应用,JTables, JcomboBoxes和JformattedTextFields连接数据库可以节约大量的开发时间。对于Web应用,数据感知标签库也可以加速开发。任何一个主流的持续性框架都比不上数据感知组件这样适合面向表格的框架。

在面向对象的世界里,很多观点都反对数据感知组件。一个常见的观点就是GUI和数据库不能共享同一个结构。一些客户端应用的确是这样的,但是对于面向CRUD的客户端,数据感知组件能节约大量的开发时间。仅仅因为数据感知组件不能在所有应用中使用,不是一个足以反对它的原因。

开发者的另外一个担忧是,害怕使用数据感知组件将对特定的数据库和IDE产生依赖。的确,一些数据库和IDE的开发商制造了一个绑定在特定数据库和IDE上的GUI组件库。但是你如果是具有使用JDBC和ANSI SQL-92语法的组件库,这个库即将和提供商无关。

事实上,对于数据感知组件重要性正在面向对象的世界中慢慢得到重视。甚至SUN公司都已经从开源项目JDesktop Network Components中意识到这种需求。

这篇文章就是讨论一个已经存在的面向表格的持续性框架——Butler。

l         对象模型

Butler具有一系列专门用来描述数据库schema结构的类:

u       Table:描述表结构

u       Column:代表表中的列

u       ForeignKey:两个表之间的外键。

这些类只用来代表数据库的结构(DDL,数据描述语言)。当从数据库中读写内容的时候,值对象也是需要的。什么可以比一个叫做Record的Java类能更自然的代表表中的记录呢?

l         取得记录

通过主键的值来取得记录,你可以调用对应表的实例里面的findByPK()方法,取代从需要的表中使用Select。方法的参数就是主键的值。例如:

       Record rec = tableRef.findbyPK(“ABC123”);

如果想取得所有的纪录,只需要调用findAll()方法,这个方法返回记录的列表,而不是一条单独的记录。

对于其他复杂的查询,则必须使用Query类,这个类代表一个SQL中的select声明。很多主流的持续性框架都是使用字符串来代表查询的。在很多方面,用字符串代表使代码紧凑,但是也带来了一些不足。使用对象和方法来构造查询则更加类型安全。大量的错误将在编译的时候被编译器发现,而不是导致运行时错误。IDE的特性,比如代码自动完成,也会使程序员使用Java语言构建查询比使用字符串简单。

Butler中的查询总是具有一个起始表(或者称作主表),这个表代表记录查询的来源。它也可以联合其他的表。结果还将是来自起始表中的记录列表。但是每个来自起始表的记录会和关联的表中记录关联,这些可以通过getRelatedRecord()和getRelatedRecords()方法进行访问。这就相对于JDBC提供了一个很大的不同(或者称作优势),在JDBC中,查询的结果总是二维的。通过记录分层,它还可以被更新或者简单的进行更复杂的结果处理。

Butler使用Filter子类来指定需要选择的记录。例如,EqualsFilter简单的比较提供的值是否和列的值相同。Filter表达用来替代你在SQL声明中所有逻辑操作符。

指定记录排列顺序可以使用addSortCritera()方法。这和SQL中的order by子句对应。

把所有的放在一起,那么一个简单的查询将是:

Query q = orderTable.createQuery();

q.join(orderDetailTable);

q.addColumn(orderTable.getColumn("OrderID"));

q.addColumn(orderTable.getColumn("OrderDate"));

q.addColumn(orderDetailTable.getColumn("ProductID"));

q.addColumn(orderDetailTable.getColumn("Quantity"));

EqualsFilter filter;

filter = new EqualsFilter(orderTable.getColumn("CustomerID"))

q.setFilter(filter);

q.addSortCritera(orderTable.getColumn("OrderDate"));

QueryInstance qi = q.createInstance();

filter.populate(qi, "BLONP");

RecordList recList = qi.run();

Butler对很多类提供内置的XML支持。一个查询结果(RecordList)可以被转换成如下的XML格式:

    <records table="Order">

    <record>

      <column name="OrderID">123</column>

      <column name="OrderDate">2004-08-29</column>

      <records fk="FK_Order_OrderDetail">

        <record>

          <column name="ProductID">P01</column>

          <column name="Quantity">2</column>

        </record>

        <record>

          <column name="ProductID">P02</column>

          <column name="Quantity">4</column>

        </record>

      </records>  

    </record>

  </records>

       这对于生成报表非常有用,可以很方便的转换成用于生成PDF文档的格式化对象,查询结果的层次化结构(相对二维结构)使它成为可能。

l         更新纪录

在Butler中,更新数据库记录非常简单。只需要调用记录实例的set()方法,以列名和值作为参数,来更新你需要的列。接着调用save()方法:

orderRec.set("OrderDate", orderDate);

  orderRec.set("ShippingDate", shippingDate);

  orderRec.save();

插入记录时首先调用对应的表对象的addRecord()方法,接着设置列的值和保存记录:

  orderRec = orderTab.addRecord();

  orderRec.set("OrderID", new Integer(123));

  orderRec.set("OrderDate", orderDate);

  orderRec.save();

删除记录同样简单。只需要调用记录对象的delete()方法。如果你想删除多条记录,则需要使用DeleteQuery类。它和Query类很类似,你需要指定一个filter来代表你需要删除的记录:

  deleteQ = orderTab.createDeleteQuery();

  filter = new EqualsFilter(orderTable.getColumn("CustomerID"));

  deleteQ.setFilter(filter);

  QueryInstance qi = q.createInstance();

  filter.populate(qi, "BLONP");

  qi.run();

Butler还提供了注册记录监视(triggers)的功能,可以给表注册一个RecordListener,在每次更新、插入、删除的之前和之后,将调用对应的事件方法。

l         生成器

如上面的例子一样,列名和表名以字符串的形式给出。程序员可能会键入错误的表名,这将造成运行时错误。为了防止这种情况,Butler可以使用生成器类生成包含每个列的get和set方法的Table和Record子类。

生成器也可以以另外一种形式来使用。产生的子类也包含数据库的结构信息。Butler不必通过JDBC在运行时获得数据的元数据,这被证明对于一些数据库非常耗时。原数据在产生的时候被取得。如果不必生成子类,也可以生成描述数据库结构的XML文件。

l         数据类型

到现在为止,这篇文章已经描述了生成JDBC调用的简单方式。但是Butler也包含了一些JDBC以外的特性。

以数据库为中心的应用总是包含数据的校验和格式化。当用户输入数据的时候,在存入数据库以前必须进行校验。在将数据提供给用户以前,它必须被进行一定的格式化。

在Butler中,每个表中的列都能和一个Datatype对象进行关联。Datatype能校验和格式化列的值。Butler对于字符串、数字值和日期有内值的Datatype实现。但是程序员也可以编写个性化的Datatype类实现处理个性化的数据类型,如电话号码,地址,甚至象图片这样的大数据对象。

上面描述的Butler类可以看作是为了简化和增强数据库编程,而在JDBC上增加的一个层。使用这些类不必改变应用的结构。可以在任何具有JDBC的地方使用。

下面我将介绍数据感知Swing组件。使用这些类需要改变应用的结构,但是数据库结构将不再和客户端不可见。

l         Swing组件

在以数据库为核心的客户端应用中,你会发现很多JtableS和数据库表关联的例子。实现这样的表经常耗费很多的时间。但是使用RecordListTable类可以节约不少的时间。程序员只需要告诉数据库中的什么表和列需要显示,以及将RecordList指派给RecordListTable即可。相关记录(多对一关系)中的列也可以被显示。RecordListTable允许更新、插入和删除记录。例如:

recListTable = new RecordListTable(orderTab);

  recListTable.addColumn(orderTab.getColumn("OrderID"));

  recListTable.addColumn(orderTab.getColumn("CustomerID"));

  recListTable.addColumn(orderTab.getForeignKey("FK_Orders_Customers"),

                         customerTab.getColumn("CompanyName"));

  recListTable.recordListSelected(orders);

如果记录的内容需要在RecordListTable以外编辑详细的内容,可以使用RecordEditor类。该类提供一个用来编辑记录的面板,为表中的每列(或者指定特定的列)都提供编辑组件。

RecordEditor实现了ActionListener接口,new命令告诉RecordEditor增加新的纪录,save命令保存当前记录。例如:

  editor = new RecordEditor(orderTab);

  editor.add(orderTab.getColumn("OrderID"));

  editor.add(orderTab.getColumn("OrderDate"));

 

  saveButton = new JButton("Save");

  saveButton.setActionCommand("save");

  saveButton.addActionListener(editor);

为了个性化层次,可以使用RecordController代替RecordEditor。不可见的组件将自动产生。RecordController有一个用来产生编辑组件的工厂方法。程序员只需要将这些组件放在需要的位置:

  controller = new RecordController(orderTab);

  ValueEditor editor;

  Column col = orderTab.getColumn("OrderDate");

  editor = controller.createColumn(col)

  panel.add(editor);

对于RecordEditor来说,RecordControler的工作方式和RecordSelectionListener类似。

在很多客户端中,已有记录的列表(RecordListTable),在一行(记录)被选中时,选中记录应该在一个详细视图(RecordEditor或者RecordController)中显示。为了在Butler中增加这种功能,只需要将RecordEditor以RecordSelectionListener的形式注册给RecordListTable:

  recordListTable.addRecordListTable(recordEditor);

在很多客户端中,用户需要首先选中他需要显示或者编辑的记录的能力。在Butler中,可以使用QueryPanel来增加这种能力,QueryPanel获得一个Query后将产生一个对应的GUI,可以在里面输入过滤器获得的值。如果结果需要在RecordListTable中显示,只需要将RecordListTable以RecordSelectionListener的形式注册给QueryPanel:

  query = orderTab.createQuery();

  query.setFilter(new EqualsFilter(orderTab.getColumn("CustomerID")));

 

  panel = new QueryPanel(query);

  recListTable = new RecordListTable(orderTab);

  panel.addRecordSelectionListener(recListTable;

如果需要个性化的层次,可以使用和QueryPanel对应的QueryController。

上面介绍的是一些常用的数据感知组件,如果你观察一个企业客户端应用,你会在很多画面中发现以下的模式:在应用画面的上面是用来输入查询参数和查询按钮的部分(QueryPanel),下面是用来显示查询结果的列表或者表格(RecordListTable),再下面,是一个类似弹出窗口的用来编辑记录的详细视图(RecordEditor)。

如果你需要创建这样模式的客户端,同时你不需要个性化层次,你不必手动设计这些组件。相反,使用SimpleForm类创建这样结构的画面,只需要几行代码。

l         总结

这篇文章描述了非主流的数据库编程解决方案。这种方

RecordEditor:固定宽度,Csv和现有Xml文件的编辑器。-开源 RecordEditor是用于平面文件(定界和固定字段位置)的数据文件编辑器。 它支持Unix / PC / Legacy(例如Mainframe)文件格式,包括文本文件和二进制文件。 编辑器使用记录布局描述来格式化文件。 这是固定宽度(文本或二进制)文件,Cobol数据文件,大型机文件和复杂的Csv文件的理想选择。 Cobol抄写本可用于格式化Cobol数据文件。 除提供编辑器外,还提供以下实用程序*格式化比较*文件复制和重新格式化实用程序* FileWizard,用于计算文件格式。 通常,它可以在文件中同时找到文本字段和二进制/打包十进制字段。对于Simple Csv,您应该查看其姊妹项目reCsvEditor。 注意:核心编辑器代码也用于“协议缓冲区编辑器”和“ Avro编辑器”中 立即下载

相关推荐

Qwen3.6-27B本地部署实战:LM Studio配置、硬件门槛与避坑指南

大语言模型本地部署是当前AI工程落地的核心能力之一,其本质是将高参数量模型(如27B级)在受限硬件环境下实现低延迟、高稳定推理。关键技术原理涵盖量化压缩(如GGUF格式与q4_k_m精度权衡)、GPU显存分配策略(KV Cache管理与Offloading机制)、以及运行时环境兼容性(CUDA驱动、llama.cpp后端版本)。该能力直接决定私有化AI应用的技术可行性与成本边界,广泛应用于企业知识库构建、代码辅助、长文档分析等对数据主权和响应确定性要求高的场景。本文聚焦Qwen3.6-27B这一典型27B模

weixin_33272631的博客 468

XMLEditor编辑器 - 极致体验的XML文件编辑工具

XMLEditor编辑器 - 极致体验的XML文件编辑工具 【下载地址】XMLEditor编辑器-极致体验的XML文件编辑工具 XML Editor 是一款专为 XML 文件设计的编辑工具,以其直观的树状图显示和高效的编辑功能著称。通过清晰的树状结构展示,用户可以轻松理解并编辑复杂的 XML 文件。编辑器支持多种格式,包...

gitblog_06771的博客 1272

STM32CubeIDE入坑指南

一 前言 在科技日新月异的今天,作为从事效率为先的苦逼 IT 行业,秉承着我不入地狱谁入地狱的伟大革命精神,我决定再一次做第一个吃螃蟹的人,通过自身的入坑过程,为大家测试STM32CubeIDE这款新式工具。(其实是为了我能省点时间,快点做完项目,多挣点钱买几瓶肾气丸) 二 看一看别人是如何入坑的 二 手把手带你入坑 三 相关资料 ...

CH的博客 1万+

XML文件编辑器(XML Editor)介绍 及 相关开源资料

1.Pollo 界面简洁,友好,支持鼠标拖拉,最重要的是开源!Some of its features:Java-based, and thus cross-platform. Pollo has been reported to work on Windows and Linux variants, HP/UX11 and OS X. Drag-and-drop of nodes in and

技术与人生--differ1的专栏 9625

电赛经验分享——赛前准备

⏩ 大家好哇!我是小光,想要成为系统架构师的嵌入式爱好者。⏩在之前的电赛中取得了省一的成绩,本文对电赛比赛前需要准备什么做一个经验分享。加入小光嵌入式交流群(qq群号:737327353)免费获取博主所有资料哦!

qq_52608074的博客 7781

固态变压器SST 1.1 课程整体框架与学习路径

本课程围绕固态变压器(SST)全生命周期工程化流程设计,构建"规范要求-理论基础-设计方法-仿真验证-工程落地"的闭环学习体系,完整覆盖GB/T 40429-2021标准要求。课程分为基础认知、核心设计、合规验证、工程落地和前沿拓展五大模块,采用理论讲解与工程实践深度融合的教学路径,通过规范条款拆解、仿真预验证、硬件实现、试验检测等环节,培养学员从设计到落地的完整能力。课程强调标准合规性,每个设计环节均有明确规范约束,并提供标准化工程模板,确保学习成果可直接应用于实际项目开发。

技术工作者 998

C语言 学习

其中,#include 预处理器指令 int main(void) main()总是第一个被调用的函数 C语言有6种语句,标号语句,复合语句,表达式语句,选择语句,迭代语句,跳转语句。 圆括号表明main()是一个函数名,int 表明main()函数返回一个整数,void表明main()不带任何参数 /*注释*/ stdio.h文件包含了供编译器使用的输入输出函数,文件名的含义是“标准输入/输出头文件” 头文件:在C程序顶部的信息集合叫头文件。头文件可以定义一些常...

qq_45444021的博客 2060

激光雷达+相机标定避坑指南:手把手教你用KITTI数据完成坐标转换

本文详细介绍了激光雷达与相机标定的实战指南,利用KITTI数据集完成精准坐标转换。从数据准备、工具链搭建到标定矩阵加载与验证,再到坐标转换流水线的工程实现,提供了全面的避坑技巧和工程实践建议。特别强调了多传感器融合中的常见问题及解决方案,帮助开发者提升自动驾驶和机器人感知系统的环境感知精度。

book8的博客 836

C Primer Plus 第2章程序示例

第2章 // 程序清单2.1 # include <stdio.h> int main(void) { int num; num =1; printf("I am a simple"); printf("computer. \n"); printf("My favorite number is %d because it is first. \n",num); //getchar(); //程序输出在屏幕上一闪而过时添加此行代码 return 0;

YWH199861的博客 646

YOLOv8改进,YOLOv8添加可变性卷积DCNv2

DCNv2对原始的DCNv1进行了改进,可变形卷积网络的卓越性能源于其适应对象几何变化的能力。通过对其自适应行为的检查,虽然对其神经特征的空间支持比常规的ConvNets更接近于对象结构,但这种支持可能远远超出感兴趣区域,导致特征受到不相关图像内容的影响。为了解决这个问题,我们提出了一种可变形卷积网的重新表述,通过提高建模能力和更强的训练,提高了其专注于相关图像区域的能力。通过更全面地集成网络中的可变形卷积,并引入扩展变形建模范围的调制机制,增强了建模能力。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 3607

【系统分析师】2026年上半年真题:案例分析-答案及详解(回忆版)

案例一聚焦因果分析法(鱼骨图)的应用,分析企业订单履约问题。问题1阐述因果分析法定义及常见方法(鱼骨图、5个为什么等);问题2将8个原因归类为人员、方法、合同等5类;问题3筛选适合鱼骨图的场景(如系统响应慢、服务器故障等),强调其适用于复杂根因分析。 案例二对比嵌入式系统中Linux与RTOS的差异(实时性、资源占用等),结合智能监控终端需求推荐Linux+四核ARM方案(高算力、性价比),并列选Linux的5大优势(生态成熟、多任务支持等)。 案例三设计互联网医院系统用例图(患者、医生等参与

数据知道的博客 1364

Excel 支持运行 Python 代码,做表格也要学编程了?

8 月 22 日,微软宣布同 Anaconda 合作,为 Excel 带来 Python 整合。整合了 Python 后的 Excel 可以直接在单元格中运行 Python 代码,使用常用的 Python 库(例如 pandas、numpy、matplotlib 等)来进行统计学运算、绘图等,甚至也可以加载一些机器学习库。由于在云端进行运算,Python in Excel 并不要求用户在计算机上预先安装任何环境,有 Excel 程序和互联网连接即可开始编程。

优快云_224022的博客 1032

100天精通Python(可视化篇)——第80天:matplotlib绘制不同种类炫酷柱状图代码实战(簇状、堆积、横向、百分比、3D柱状图)

0. 专栏导读 1. 普通柱状图 2. 簇状柱形图 3. 堆积柱形图 4. 横向柱状图 5. 横向双向柱状图 6. 百分比堆积柱形图 7. 3D柱形图 8. 3D堆积柱形图 9. 3D百分比堆积柱形图

努力让自己发光,对的人才能迎着光而来 2万+

2.6 多个函数

但是,在程序中使用函数时,需要让编译器知道该函数的存在及其属性,这就是函数原型的作用。函数原型包含了函数的返回类型、函数名和参数列表,它告诉编译器正在使用某个函数,并指明了该函数的属性,例如是否带参数、是否有返回值等。在本例中,butler()函数的原型是void butler(void),表示该函数不带参数,没有返回值。在程序中,函数调用的位置决定了函数的执行顺序,而不是函数定义在文件中的位置。函数定义包含函数头和函数体,函数头与函数原型的形式基本相同,但是函数体中包含了函数的具体实现。

weixin_47712251的博客 660

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C语言函数

关于C语言函数 C语言函数 介绍C语言中函数的三种情况,先通过一个简单的示例说明,代码如下: 函数原型(prototype) 如图,;函数原型告知编译器在程序中要使用该函数。函数原型是一种声明形式,告知编译器正在使用某函数,因此函数原型也被称为函数声明(function declaration)。 同时函数原型还指明了函数的属性。例如:第一个void表明——butler()函数没有返回值。 函数...

PiKeHuPu的博客 1970

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

python操作excel表格【自定义表格样式基础】,2024年最新附项目源码

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。

2401_84138927的博客 1322

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Excel VBA编程教程(基础一)

VBA介绍 Visual Basic for Applications(VBA)是 VisualBasic 的一种宏语言,是微软开发出来在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展 Windows 的应用程序功能,特别是Microsoft Office软件。 说简单点,VBA 是运行在 Microsoft Office 软件之上,可以用来编写非软件自带的功能的编程语言。Office 软件提供丰富的功能接口,VBA 可以调用它们,实现自定义的需求。基本上,能用鼠标和键盘能做的

O_MMMM_O的博客 6万+

必学的20个Excel表格操作python脚本!

首先,我们创建一个示例的Excel文件bank_data.xlsx,并填充一些示例数据。1. 读取Excel文件使用场景:从Excel中加载数据进行后续处理。代码解释:使用pandas.read_excel函数读取Excel文件。2. 写入Excel文件使用场景:将处理后的数据保存到新的Excel文件。代码解释:使用DataFrame.to_excel方法写入Excel文件。3. 更新特定单元格使用场景:修改Excel中的某个具体值。代码解释:通过索引定位单元格并赋新值。

2301_78217634的博客 2215

如何用python做一个表格,python怎么快速做表格

这篇文章主要介绍了如何用python做一个表格,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。⚠️1.Excel的基本组成2.一份报表自动化的流程3.报表自动化实战4.将不同的结果进行合并。

w666666Wwwwwww的博客 1142

自定义c函数原型

【代码】自定义c函数原型。

2302_79270679的博客 203

C语言学习记录-two_func.c程序

two_func.c程序 程序清单2.3(C primer plus) /*two_func.c -- 一个文件中包含两个函数*/ #include<stdio.h> void butler(void); /* ANNSI/ISO C 函数原型*/ //在此告知编译器在程序中要使用该用函数. int main(void) { printf("I will summon the butler function.\n"); butler(); //调用函数 printf(

ax7z1的博客 672

Python编程技巧:如何用Python制作超炫的表格?!

如何用Python制作超炫的表格?!众所周知,命令行展现复杂的文本看起来着实累人,于是就想着能像表格那样展示,那看起来就舒服多了。

白帽阿叁的博客 793

用 Python 处理 Excel 的 14 个常用操作!

这也是我写这篇文章的初衷。废话不说了,直接进入正题。vlookup是excel几乎最常用的公式,一般用于两个表的关联查询等。所以我先把这张表分为两个表。需求:想知道df1的每一个订单对应的利润是多少。利润一列存在于df2的表格中,所以想知道df1的每一个订单对应的利润是多少。用excel的话首先确认订单明细号是唯一值,然后在df1新增一列写:=vlookup(a2,df2!a:h,6,0) ,然后往下拉就ok了。(剩下13个我就不写excel啦)那用python是如何实现的呢?

Trb201013的博客 9226

Matlab编程技巧:写入Excel表格

本文研究如何将Matlab变量的内容写入Excel表格,以及相关的一些技巧。 文章目录1 函数2 简单示例3 写入表格的注意点3.1 写入单个单元格3.2 写入多个单元格3.3 写入0开头的数字3.4 指定所有的四个参数3.5 避免用for循环 1 函数 写入Excel表格的函数比较简单,只有一个函数如下: xlswrite(filename,A,sheet,xlRange) 其中的参数含义如下: 参数 含义 filename 文件名,可以是绝对路径也可以是相对路径 A 写入表格文件的

u013288925的博客 5万+
上一篇: 开源密码管理软件项目说明(附源代码)
下一篇: 2004年我们的通病,看看你占几条?(转贴)
java2000_test
博客等级 码龄19年 10粉丝 320原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值