編程中,有時候需要以表格的形式輸出數據,使其更易于閱讀和理解。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小時內與您取得聯系。