编程中,有时候需要以表格的形式输出数据,使其更易于阅读和理解。Python提供了多种方法来创建和输出表格数据。本文将介绍如何使用不同的方法制作输出表格,并提供详细的示例代码,以帮助大家更好地理解和应用这些技巧。
最简单的方法是使用制表符(Tab)字符来分隔列,这种方式适用于文本输出。
以下是一个示例:
# 数据
data=[
["Name", "Age", "City"],
["Alice", "30", "New York"],
["Bob", "25", "Los Angeles"],
["Charlie", "35", "Chicago"]
]
# 输出表格
for row in data:
print("\t".join(row))
在这个示例中,首先定义了一个包含表格数据的列表data,然后使用join()方法将每一行的数据以制表符分隔并输出到屏幕上。
Python的字符串格式化功能可以更灵活地控制输出表格的样式。可以使用str.format()方法或f-字符串来格式化输出。
以下是一个示例:
# 数据
data=[
["Name", "Age", "City"],
["Alice", "30", "New York"],
["Bob", "25", "Los Angeles"],
["Charlie", "35", "Chicago"]
]
# 输出表格
for row in data:
print("{:<10} {:<5} {:<10}".format(*row))
在这个示例中,使用字符串格式化来定义每列的宽度,并使用<来指定左对齐。这样可以确保表格数据在列中对齐。
如果需要更复杂的表格操作,可以考虑使用第三方库,如tabulate或prettytable。这些库提供了更多的功能和选项来创建和输出表格。
以下是使用tabulate库的示例:
from tabulate import tabulate
# 数据
data=[
["Name", "Age", "City"],
["Alice", "30", "New York"],
["Bob", "25", "Los Angeles"],
["Charlie", "35", "Chicago"]
]
# 输出表格
print(tabulate(data, headers="firstrow", tablefmt="grid"))
这个示例中,首先安装tabulate库(使用pip install tabulate),然后使用它的tabulate()函数来输出表格。可以指定不同的输出格式,例如,tablefmt="grid"用于创建网格形式的表格。
如果需要在网页上显示表格,可以考虑使用HTML表格。
以下是一个示例,演示如何使用Python生成HTML表格:
# 数据
data=[
["Name", "Age", "City"],
["Alice", "30", "New York"],
["Bob", "25", "Los Angeles"],
["Charlie", "35", "Chicago"]
]
# 生成HTML表格
html_table="<table>"
for row in data:
html_table +="<tr>"
for cell in row:
html_table +="<td>{}</td>".format(cell)
html_table +="</tr>"
html_table +="</table>"
# 输出HTML
print(html_table)
在这个示例中,使用循环生成HTML标签,以创建包含表格数据的HTML表格。这个方法适用于在网页上显示数据。
Pandas 是一个强大的数据分析库,它提供了灵活的数据结构和数据操作功能,包括表格的创建和处理。
以下是一个示例,演示如何使用 Pandas 创建和输出表格:
import pandas as pd
# 数据
data=[
["Name", "Age", "City"],
["Alice", 30, "New York"],
["Bob", 25, "Los Angeles"],
["Charlie", 35, "Chicago"]
]
# 创建DataFrame对象
df=pd.DataFrame(data[1:], columns=data[0])
# 输出表格
print(df)
在这个示例中,首先导入 Pandas 库,并将表格数据存储在一个列表中。然后,使用 Pandas 的 DataFrame 对象来创建表格,并通过 print() 函数输出。Pandas 提供了丰富的数据操作和分析功能,可以轻松处理大规模数据集。
另一个创建和输出表格的库是 PrettyTable,它提供了一种简单的方式来创建漂亮的文本表格。
以下是一个示例:
from prettytable import PrettyTable
# 数据
data=[
["Name", "Age", "City"],
["Alice", 30, "New York"],
["Bob", 25, "Los Angeles"],
["Charlie", 35, "Chicago"]
]
# 创建PrettyTable对象
table=PrettyTable(data[0])
for row in data[1:]:
table.add_row(row)
# 输出表格
print(table)
在这个示例中,首先安装 PrettyTable 库(使用 pip install prettytable),然后创建一个 PrettyTable 对象,并使用 add_row() 方法添加行数据。最后,通过 print() 函数输出漂亮的文本表格。
如果希望在终端中以更美观的方式显示表格,可以考虑使用终端表格库,如 terminaltables。
以下是一个示例:
from terminaltables import AsciiTable
# 数据
data=[
["Name", "Age", "City"],
["Alice", 30, "New York"],
["Bob", 25, "Los Angeles"],
["Charlie", 35, "Chicago"]
]
# 创建AsciiTable对象
table=AsciiTable(data)
# 输出表格
print(table.table)
在这个示例中,首先安装 terminaltables 库(使用 pip install terminaltables),然后创建一个 AsciiTable 对象,并通过 table 属性输出表格。这种方式在终端中以更漂亮的方式显示表格。
制作输出表格在各种情况下都是有用的,无论是文本报告、数据分析还是终端应用。Python 提供了多种方法和库来创建和输出表格,可以根据具体需求选择最适合的方法。希望本文中的示例代码能帮助大家更好地处理表格数据,并提高编程效率。无论你是初学者还是有经验的开发者,掌握这些表格处理技巧都将是一个有用的技能。
如今各类BI产品大行其道,“数据可视化”成为一个热门词汇。相比价格高昂的各种BI软件,用Excel来制作动态报表就更加经济便捷。今天小编就将为大家介绍一下如何使用葡萄城公司的纯前端表格控件——SpreadJS来实现一个Excel动态报表:
制作这样的数据大屏首先必须要明确目的,比如在这里围绕销售金额制作一个数据大屏,首先点击数据源,然后点击插入找到数据透视表,随后将年份放在行字段,然后将销售金额放在值字段,因为在这里数值比较大,可以选择销售金额这一列数据,然后按快捷键Ctrl 1调出格式窗口,点击自定义,将类型设置为0!.0,这样的话就变为了万元显示,然后在设计中找到总计,选择对行和列禁用,将数据透视表中的总计禁用掉。
选择数据区域,然后在图表中找到饼图,随后为饼图添加数据标签,紧接着点击标签按Ctrl + 1调出格式窗口,勾选类别名称然后将分隔符设置为新的文本行,最后将无用的图例删掉即可,至此的第一个图表就制作完毕了。
为了添加更多图表,复制刚才设置的数据透视表,在复制的数据透视表中将年份这个字段拖走,然后将省份这个字段放在行字段,最后将数字更改为万元显示,然后插入一个横向的条形图,将无用的图例删除掉即可。需要注意的是,你需要设置几个图表,就需要复制几次数据透视表,更改为自己需要的字段,最后插入图表,在这里就以3个为例跟大家演示制作方法。
为了让多张图表能够联动变化,点击数据透视表,在工具栏中找到插入切片器,然后分别勾选,年份,省份,厂商点击确定,这样的话就插入了3个切片器,随后将他们更改下大小放在合适的位置即可。随后点击一个切片器,在切片器选项中选择链接到报表,勾选其他的两个报表即可,以此类推,其余的2个切片器也需要这样设置,设置完毕后就制作完毕了。
至此,一张简单的可视化数据报表就制作好了。有时候,制作好的可视化报表需要通过网络让更多的人查阅,那么有什么好办法呢?
下面小编为大家介绍如何使用借助SpreadJS实现在线化查看:
首先打开SpreadJS的学习指南:
按照学习指南上的代码进行编程实践:
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Spread-CDN</title>
<link rel='icon' href='./assets/images/logo.png' type='image/x-icon'>
<link
href='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets/styles/gc.spread.sheets.excel2013white.css'
rel='stylesheet' type='text/css' />
<script type='text/javascript'
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets/dist/gc.spread.sheets.all.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-print/dist/gc.spread.sheets.print.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-excelio/dist/gc.spread.excelio.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-io/dist/gc.spread.sheets.io.min.js'></script>
<script
src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.min.js'></script>
<script>
GC.Spread.Common.CultureManager.culture('zh-cn')
</script>
<style>
* {
margin: 0;
padding: 0;
}
#app {
overflow: hidden;
}
#spread-container {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<input type="file" id="file"/>
<div id='app'>
<div id='spread-container'></div>
</div>
<script>
const spread=new GC.Spread.Sheets.Workbook('spread-container')
let sheet=spread.getActiveSheet()
const fileElement=document.querySelector('#file')
fileElement.addEventListener('change', function (e) {
const file=e.target.files[0]
spread.import(file, ()=>{
fileElement.style.display='none'
})
})
</script>
</body>
</html>
这里使用<input type="file" />来选择本地文件,在成功导入后将该元素隐藏,以便在全屏预览报表时没有多余元素干扰。想导入其他模板时,只需刷新页面,用来选择模板文件的按钮就又出现了。
最后导入在Excel中制作好的报表模板,一张可在线浏览的动态Excel报表就大功告成了。
文章只是简单演示,没有加复杂的样式,如果您想做出更好的显示效果,可以充分调用自己的艺术细胞,做出更加美观炫酷的动态报表,甚至做一个数据大屏也是可以实现的,如果您对的SpreadJS感兴趣的话,也欢迎访问SpreadJS官网。
poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库。同类型的FreeMarker或Velocity基于文本模板和数据生成新的html页面或配置文件。而poi tl是一个基于Word模板和数据生成新文档的Word模板引擎。
Word模板具有丰富的样式。Poi-tl将在生成的文档中完美地保留模板中的样式。也可以设置标记的样式。标记的样式将应用于替换的文本,因此您可以专注于模板设计。
poi-tl是一个“无逻辑”模板引擎。没有复杂的控制结构和变量分配,只有标签,有些标签可以用文本、图片、表格等代替,有些标签会隐藏某些文档内容,而另一些标签会循环一系列文档内容。
像变量赋值或条件语句这样的“强大”构造可以很容易地在模板系统中专门修改应用程序的外观。。。然而,以分离为代价,将模板本身变成应用程序逻辑的一部分。
poi-tl支持自定义函数(插件),函数可以在Word模板的任何地方执行,在文档的任何地方做任何事情都是poi-tl的目标。
GitHub - Sayi/poi-tl: Generate awesome word(docx) with template
Poi-tl Documentation (deepoove.com)
Apache License 2.0
下面表格是官方文档中提供的与其他模板引擎的对比
方案 | 移植性 | 功能性 | 易用性 |
Poi-tl | Java跨平台 | Word模板引擎,基于Apache POI,提供更友好的API | 低代码,准备文档模板和数据即可 |
Apache POI | Java跨平台 | Apache项目,封装了常见的文档操作,也可以操作底层XML结构 | 文档不全,这里有一个教程:Apache POI Word快速入门 |
Freemarker | XML跨平台 | 仅支持文本,很大的局限性 | 不推荐,XML结构的代码几乎无法维护 |
OpenOffice | 部署OpenOffice,移植性较差 | - | 需要了解OpenOffice的API |
HTML浏览器导出 | 依赖浏览器的实现,移植性较差 | HTML不能很好的兼容Word的格式,样式糟糕 | - |
Jacob、winlib | Windows平台 | - | 复杂,完全不推荐使用 |
Word模板引擎功能 | 描述 |
文本 | 将标签渲染为文本 |
图片 | 将标签渲染为图片 |
表格 | 将标签渲染为表格 |
列表 | 将标签渲染为列表 |
图表 | 条形图(3D条形图)、柱形图(3D柱形图)、面积图(3D面积图)、折线图(3D折线图)、雷达图、饼图(3D饼图)、散点图等图表渲染 |
If Condition判断 | 根据条件隐藏或者显示某些文档内容(包括文本、段落、图片、表格、列表、图表等) |
Foreach Loop循环 | 根据集合循环某些文档内容(包括文本、段落、图片、表格、列表、图表等) |
Loop表格行 | 循环复制渲染表格的某一行 |
Loop表格列 | 循环复制渲染表格的某一列 |
Loop有序列表 | 支持有序列表的循环,同时支持多级列表 |
Highlight代码高亮 | word中代码块高亮展示,支持26种语言和上百种着色样式 |
Markdown | 将Markdown渲染为word文档 |
Word批注 | 完整的批注功能,创建批注、修改批注等 |
Word附件 | Word中插入附件 |
SDT内容控件 | 内容控件内标签支持 |
Textbox文本框 | 文本框内标签支持 |
图片替换 | 将原有图片替换成另一张图片 |
书签、锚点、超链接 | 支持设置书签,文档内锚点和超链接功能 |
Expression Language | 完全支持SpringEL表达式,可以扩展更多的表达式:OGNL, MVEL… |
样式 | 模板即样式,同时代码也可以设置样式 |
模板嵌套 | 模板包含子模板,子模板再包含子模板 |
合并 | Word合并Merge,也可以在指定位置进行合并 |
用户自定义函数(插件) | 插件化设计,在文档任何位置执行函数 |
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.1</version>
</dependency>
implementation 'com.deepoove:poi-tl:1.12.1'
ConfigureBuilder builder=Configure.builder();
poi-tl所有的标签都是以{{开头,以}}结尾,这是为了致敬Google CTemplate。标签可以出现在任何位置,包括页眉,页脚,表格内部,文本框等,表格布局可以设计出很多优秀专业的文档,推荐使用表格布局。
当然如果你更偏爱freemarker ${} 的方式,也可以添加如下配置修改标签的前后缀配置:
builder.buildGramer("${", "}");
XWPFTemplate template=XWPFTemplate.compile("template.docx", builder.buid());
poi-tl加载使用XWPFTemplate.compile方法来加载模板,支持模板以绝对路径(String),File、InputStream、XWPFDocument四种格式传入。
poi-tl数据类似于哈希或者字典,可以是Map结构(key是标签名称):
Map<String, Object> data=new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");
template.render(dataMap);
poi-tl以流的方式进行输出:
template.write(OutputStream stream);
可以写到任意输出流中,比如文件流:
template.write(new FileOutputStream("output.docx"));
如网络流:
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");
// HttpServletResponse response
OutputStream out=response.getOutputStream();
BufferedOutputStream bos=new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out);
{{var}}
代码示例
put("name", "Sayi");
put("author", new TextRenderData("000000", "Sayi"));
put("link", new HyperlinkTextRenderData("website", "http://deepoove.com"));
put("anchor", new HyperlinkTextRenderData("anchortxt", "anchor:appendix1"));
除了new操作符,还提供了更加优雅的工厂 Texts 和链式调用的方式轻松构建文本模型。
链式代码示例
put("author", Texts.of("Sayi").color("000000").create());
put("link", Texts.of("website").link("http://deepoove.com").create());
put("anchor", Texts.of("anchortxt").anchor("appendix1").create());
图片标签以@开始:{{@var}}
// 指定图片路径
put("image", "logo.png");
// svg图片
put("svg", "https://img.shields.io/badge/jdk-1.6%2B-orange.svg");
// 设置图片宽高
put("image1", Pictures.ofLocal("logo.png").size(120, 120).create());
// 图片流
put("streamImg", Pictures.ofStream(new FileInputStream("logo.jpeg"), PictureType.JPEG)
.size(100, 120).create());
// 网络图片(注意网络耗时对系统可能的性能影响)
put("urlImg", Pictures.ofUrl("http://deepoove.com/images/icecream.png")
.size(100, 100).create());
// java图片
put("buffered", Pictures.ofBufferedImage(bufferImage, PictureType.PNG)
.size(100, 100).create());
表格标签以#开始:{{#var}}
// 一个2行2列的表格
put("table0", Tables.of(new String[][] {
new String[] { "00", "01" },
new String[] { "10", "11" }
}).border(BorderStyle.DEFAULT).create());
// 第0行居中且背景为蓝色的表格
RowRenderData row0=Rows.of("姓名", "学历").textColor("FFFFFF")
.bgColor("4472C4").center().create();
RowRenderData row1=Rows.create("李四", "博士");
put("table1", Tables.create(row0, row1));
// 合并第1行所有单元格的表格
RowRenderData row0=Rows.of("列0", "列1", "列2").center().bgColor("4472C4").create();
RowRenderData row1=Rows.create("没有数据", null, null);
MergeCellRule rule=MergeCellRule.builder().map(Grid.of(1, 0), Grid.of(1, 2)).build();
put("table3", Tables.of(row0, row1).mergeRule(rule).create());
列表标签以*开始:{{*var}}
put("list", Numberings.create("Plug-in grammar",
"Supports word text, pictures, table...",
"Not just templates"));
首先我们建立一个word文件,在word文件里填充一下内容。
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.*;
import dto.Qiankuan;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.*;
public class PoitlTest {
public static void main(String[] args) throws IOException {
ConfigureBuilder builder=Configure.builder();
//获取模板的文件流
FileInputStream fileInputStream=new FileInputStream("D:\\文章\\word生成\\poi-tl\\qiantiao.docx");
HashMap<String, Object> dataMap=new HashMap<>();
//添加文本
LocalDate currentDate=LocalDate.now();
LocalDate endDate=currentDate.plusYears(1L);
dataMap.put("debtor", "陈有楚");
dataMap.put("nowYear", String.valueOf(currentDate.getYear()));
dataMap.put("nowMonth", String.valueOf(currentDate.getMonthValue()));
dataMap.put("nowDay", String.valueOf(currentDate.getDayOfMonth()));
//验证换行的情况
dataMap.put("arrears", "\n一顿老魏,\n贵州大黄牛,\nv我50");
dataMap.put("endYear", String.valueOf(endDate.getYear()));
dataMap.put("endMonth", String.valueOf(endDate.getMonthValue()));
dataMap.put("endDay", String.valueOf(endDate.getDayOfMonth()));
//添加列表
List<String> list=Arrays.asList("阿大", "阿二", "阿三");
Numberings.NumberingBuilder numberingBuilder=Numberings.of(NumberingFormat.DECIMAL);
for (String s : list) {
numberingBuilder.addItem(s);
}
dataMap.put("witness", numberingBuilder.create());
//添加图片,考虑到实际生产环境图片大都都从文件服务获取,所以这里用图片流做例子
PictureRenderData pictureRenderData=Pictures.ofStream(Files.newInputStream(Paths.get("D:\\picture\\其他\\24-05-23-142418.png")), PictureType.JPEG)
.size(300, 220).create();
dataMap.put("image1", pictureRenderData);
List<Qiankuan> qiankuanList=getQiankuanList();
//添加表格
//填充表头,表格的第一行
RowRenderData row0=Rows.of("拖欠物品", "拖欠次数", "偿还期限").center().bgColor("4472C4").create();
Tables.TableBuilder tableBuilder=Tables.of(row0);
//填充表格内容
for (Qiankuan qiankuan : qiankuanList) {
RowRenderData row=Rows.create(qiankuan.getName(), String.valueOf(qiankuan.getCount()), qiankuan.getQixian());
tableBuilder.addRow(row);
}
//MergeCellRule rule=MergeCellRule.builder().map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(1, 2)).build();
//tableBuilder.mergeRule(rule);
dataMap.put("table1", tableBuilder.create());
ChartMultiSeriesRenderData chart=Charts
.ofMultiSeries("ChartTitle", new String[] { "中文", "English" })
.addSeries("countries", new Double[] { 15.0, 6.0 })
.addSeries("speakers", new Double[] { 223.0, 119.0 })
.create();
dataMap.put("barChart", chart);
XWPFTemplate template=XWPFTemplate.compile(fileInputStream, builder.build())
.render(dataMap);
template.writeAndClose(Files.newOutputStream(Paths.get("D:\\test\\qiantiao-poitl.docx")));
System.out.println("success");
}
static List<Qiankuan> getQiankuanList() {
List<Qiankuan> list=new ArrayList<>();
Qiankuan q1=new Qiankuan();
q1.setName("一顿老魏");
q1.setCount(1);
q1.setQixian("三月内");
list.add(q1);
Qiankuan q2=new Qiankuan();
q2.setName("一顿大黄牛");
q2.setCount(1);
q2.setQixian("半年内");
list.add(q2);
Qiankuan q3=new Qiankuan();
q3.setName("特一特");
q3.setCount(3);
q3.setQixian("一周内");
list.add(q3);
Qiankuan q4=new Qiankuan();
q4.setName("v我50");
q4.setCount(5);
q4.setQixian("一周内");
list.add(q4);
return list;
}
}
*请认真填写需求信息,我们会在24小时内与您取得联系。