用 Excel 做甘特图:步骤与局限
Excel 没有"甘特图"这种图表类型。它是用一个技巧拼出来的:堆积条形图,把第一个数据系列设成透明。这招管用,十分钟就能完成, , 但有一条明确的边界。
准备数据
新建一张空白工作表,建四列:任务、开始日期、结束日期、工期。开始和结束填真实日期,工期用公式算:开始在 B2、结束在 C2,D2 输入 =C2-B2 向下填充。Excel 把日期存成序列号,相减得到的正是天数。
一个最小的例子,每项任务都从上一项结束的次日开始:
| 任务 | 开始 | 结束 | 工期 |
|---|---|---|---|
| 调研 | 7 月 1 日 | 7 月 5 日 | 5 |
| 设计 | 7 月 6 日 | 7 月 12 日 | 7 |
| 开发 | 7 月 13 日 | 7 月 26 日 | 14 |
| 测试 | 7 月 27 日 | 8 月 2 日 | 7 |
| 上线 | 8 月 3 日 | 8 月 4 日 | 2 |
上表用的是 =C2-B2+1:当天开始、当天结束的任务仍然要占一天,没有这个 +1,每条横条都会短一天,一天工期的任务干脆消失。如果你习惯把结束日期当作交接时点、让下一项任务同日开始,那就用 =C2-B2。两种约定都成立,混着用才会得到一张每一行都悄悄差一天的图。
再加一列偏移量:本任务比项目最早开始日期晚几天,=B2-$B$2。
关键一步是把偏移量和工期两列的数字格式改成"常规"或"数值"。留成日期格式的话,7 天会被读成 1900 年 1 月 7 日,横条长度全错, , 这是最常见的翻车点。
插入堆积条形图
选中任务列,按住 Ctrl 再加选偏移量列和工期列, , 结束日期列不参与作图。然后走插入 › 图表 › 条形图 › 二维条形图 › 堆积条形图。
Excel 画出每行两段的横条:第一段是偏移量,第二段是工期。此刻它还不像甘特图,这是正常的。如果系列顺序颠倒,右键选择数据,确认偏移量是系列一、工期是系列二。
把第一个系列设为不可见
在任意一段偏移量上单击一次,选中的是整个系列;双击只会选中单独一条。右键设置数据系列格式,在填充里选无填充,再把边框设为无线条, , 否则会留下一圈轮廓,把本该看不见的偏移段暴露出来。
偏移量消失后,每条工期横条就浮到了正确的起始位置, , 到这一步它已经是甘特图了。
反转顺序
Excel 的条形图会把表格第一行画在最下面,任务顺序是倒的。点选纵轴,右键设置坐标轴格式,在坐标轴选项里勾选逆序类别。
勾完之后日期轴会跑到下方。在同一面板里把横坐标轴交叉设为最大分类,它就回到顶部。
修正日期坐标轴
横轴默认从 0 开始,左边空出一大片。点选横轴,在设置坐标轴格式 › 边界里把最小值设为项目开始日期、最大值设为结束日期。这里只接受序列号:在空单元格输入日期、把格式改成"常规",显示的数字就是要填的值。
再把单位 › 主要设为 7 得到按周的网格线,把分类间距压到 20% 左右让横条更粗,最后按阶段换色、删掉图例。
一个完整算例:六项任务,然后来一次延误
上面五步是机械操作。真正决定这个文件能不能撑过一个真实项目的,是公式怎么写,以及计划一变它们会怎么样。
先说一句关于版本的话:中文版 Excel 的函数名仍然是英文, , WORKDAY、NETWORKDAYS、MAX、COUNTIF 照写不误,只有参数之间用半角逗号分隔,不是分号。国内很多人用的 WPS Office 在这一点上与 Excel 完全一致,下面所有公式原样粘贴即可,不需要改写。
这张表。一个电商官网重构项目,2026 年 3 月 2 日(周一)启动。第 1 行是表头,任务在第 2-7 行。列:A 任务、B 开始、C 结束、D 工作日、E 横条长度。法定节假日放在 H2:H5:清明补假 4 月 6 日,以及劳动节 5 月 1 日、5 月 4 日、5 月 5 日。只有 D 列是手工输入的,其余都是算出来的:
- C2,结束日期, ,
=WORKDAY(B2,D2-1,$H$2:$H$5)。那个-1很关键:WORKDAY是向前数的,周一开始、做满 5 个工作日的任务,结束日是WORKDAY(周一,4)也就是周五。漏掉它,每项任务都会长出一天。 - B3,后续每项任务的开始日期, ,
=WORKDAY(C2,1,$H$2:$H$5)。整张表之所以还能"自动重排",全靠这一条公式。 - E2,图表实际绘制的那个数, ,
=C2-B2+1,不是D2。D 是工作日,而图表横轴是含周末和节假日的自然日历,所以一项 10 个工作日的任务必须画成 12 天长的横条。把这两个数混为一谈,是 Excel 甘特图和它自己那张表对不上最常见的原因。 - 如果还想知道两个日期之间到底有几个工作日,用
=NETWORKDAYS(B2,C2,$H$2:$H$5)反查一遍,能当作校验。
把 C2、E2 向下填充到第 2-7 行,B3 向下填充到第 3-7 行:
| 行 | A, 任务 | B, 开始 | C, 结束 | D, 工作日 | E, 横条长度 |
|---|---|---|---|---|---|
| 2 | 需求调研 | 3 月 2 日(周一) | 3 月 13 日(周五) | 10 | 12 |
| 3 | 设计 | 3 月 16 日(周一) | 3 月 27 日(周五) | 10 | 12 |
| 4 | 开发 | 3 月 30 日(周一) | 4 月 27 日(周一) | 20 | 29 |
| 5 | 内容迁移 | 4 月 28 日(周二) | 5 月 21 日(周四) | 15 | 24 |
| 6 | 测试 | 5 月 22 日(周五) | 6 月 4 日(周四) | 10 | 14 |
| 7 | 上线 | 6 月 5 日(周五) | 6 月 5 日(周五) | 1 | 1 |
注意第 4 行和第 5 行:20 个工作日的开发画成 29 天长的横条,15 个工作日的内容迁移画成 24 天, , 多出来的不只是周末,还有清明和劳动节。H2:H5 这几个格子如果不填,开发会提前一天完成,内容迁移提前三天,而错误会一路累积到上线日。
坐标轴。Excel 的坐标轴边界只认序列号,不认日期。在空单元格里输入 =B2 再把格式改成"常规"就能读出来:2026 年 3 月 2 日是 46083,6 月 5 日是 46178。这两个数填进最小值和最大值,单位 › 主要填 7 得到按周的网格线。
现在改一个数。设计超了三天:只改 D3,从 10 改成 13。整条链自己重算, , 设计 4 月 1 日(周三)结束,开发 4 月 2 日至 4 月 30 日,内容迁移 5 月 6 日至 5 月 26 日,测试 5 月 27 日至 6 月 9 日,上线变成 6 月 10 日(周三)。进去三个工作日,出来三个工作日。这是这张表最好的样子,而且确实好用。
接下来是它坏掉的地方。
- 最后一条横条跑出图外了。上线挪到 6 月 10 日,超过了写死在坐标轴最大值里的 46178。横条被截断,而且没有任何提示。此后每改一次日期,都要重新读一遍序列号、重新敲一遍边界。
- 插入一行只加进来一半。在设计和开发之间插入"客户评审":Excel 会自动扩展图表的数据区域,但新行里一条公式也没有,而原来的开发行仍然指着设计。看漏了这一点,表面读起来完全正确,实际排的是错的。要是图省事加在第 7 行下面,它又落在数据区域之外,根本不显示。
- 第二个前置任务没地方放。如果测试同时要等开发和内容迁移,诚实的写法是
=WORKDAY(MAX(C4,C5),1,$H$2:$H$5)。它能用, , 但图上看不出任何连线,下一个接手的人只看得见一个日期。再给它加五天的客户评审当滞后量,就变成=WORKDAY(C3,1+5,$H$2:$H$5):一个光秃秃的5埋在公式里,任何地方都没有标注。
把 B 列写成公式,买到的是"沿单一链条重排"。它买不到一张网络。这里没有任何东西能告诉你哪两项任务在决定完工日期,因为这里没有任何东西知道它们连着。
加依赖关系与完成百分比
局限就是在这里露出来的。依赖关系没有原生支持:没有完成-开始箭头,Excel 也完全不知道一项任务约束着另一项。上面那种在开始列里引用前置任务结束日期的写法,只能应付一条单链。它根本表达不了开始-开始和完成-完成,两个前置任务要靠一个藏起来的 MAX(),而且只要有人对行排序就会无声地崩掉, , 排序移动的是值,相对引用却仍然指向"现在排在上面的那一行"。
完成百分比要靠辅助列,而且网上通行的那个做法是错的。把进度系列叠加在开始和工期之上,会让每条横条按已完成的工作量变长, , 一项 100% 的任务会画成真实长度的两倍。正确的搭法用三个系列,并且丢掉原来那个纯长度系列。设完成百分比在 F 列,加两列辅助:已完成写 =E2*F2,剩余写 =E2*(1-F2)。
按"开始、已完成、剩余"这个顺序作图:开始设无填充,已完成用深色,剩余用浅色。两段可见部分之和恒等于 E,所以每条横条都保持真实的日历跨度,并随着工作推进从左往右填满。代价是每新增一项任务都要回去核对数据区域和系列顺序, , 而区域一变,Excel 很乐意帮你把顺序重排一遍。
里程碑还要再单独建一个系列,只在里程碑日期上有值,改成散点图、标记选菱形, , 工期为零的任务在条形图里画不出任何可见形状。
另一种做法:条件格式
完全不想碰图表工具的话,可以直接在单元格里做一张条件格式甘特图。它更结实,因为没有一个带着数据区域、会悄悄过期的图表对象。
A, E 列的表原样保留。从 G 列开始在第 1 行横排一条日历:G1 写 =B2,H1 写 =G1+1,向右拖满整个项目长度, , 3 月 2 日到 6 月 5 日含首尾共 96 天,因此拖到 CX 列。把这一行的格式设成 aaa(中文版显示"一、二…日"),列宽压到 20 像素左右。
选中 G2:CX7,并且让 G2 保持为活动单元格, , 这一点很要紧,因为公式是站在活动单元格的角度写的,其余每个格子按相对位置偏移。走开始 › 条件格式 › 新建规则 › 使用公式确定要设置格式的单元格,按这个顺序加四条规则:
=AND(G$1>=$B2, G$1<=$C2), , 横条颜色。混合引用就是全部的机关:G$1锁住行,所以每一列读自己那天的日期;$B2锁住列,所以每一行读自己那项任务的起止日期。=COUNTIF($H$2:$H$5,G$1)>0, , 法定节假日,填成醒目的另一种浅色。国内的计划不标这一条几乎没法看:光看周末,谁也想不起来 5 月 4 日为什么没人干活。=WEEKDAY(G$1,2)>5, , 周末,浅灰。返回类型写2,把周一编为 1、周日编为 7,于是>5正好是周六和周日。默认的类型1从周日起算,会把错误的两天涂灰。=G$1=TODAY(), , 一条彩色左边框,这就是今天线。
规则自上而下判断,第一个填充生效,所以横条规则必须排在节假日和周末规则上面,否则每条横条都会在周六周日长出灰色条纹。调休上班的周六要单独处理:它既不该按周末涂灰,也不在节假日清单里,最省事的办法是再建一列调休日期,另加一条 COUNTIF 规则把它改回工作日底色。
这套做法的好处是日期一改格子立刻重画、打印干净、插入行的容忍度也比图表高。但里程碑和进度仍然要手写规则,而且它同样对依赖关系一无所知。
Excel 给得了什么,给不了什么
两种做法都能画出一张相当体面的进度图。但它们都不排程。横条一旦看着对了,这个区别就很容易被忘掉,所以这里直说:
| 能力 | 堆积条形图 | 条件格式 | 真正的排程工具 |
|---|---|---|---|
| 排除周末与法定节假日 | 可以,靠 WORKDAY | 可以,靠 WORKDAY | 内置 |
| 单条 FS 链自动重排 | 可以,前提是开始列是公式 | 可以,前提是开始列是公式 | 可以 |
| 看得见的依赖箭头 | 没有 | 没有 | 有 |
| 一项任务两个前置 | 只能靠隐藏的 MAX() | 只能靠隐藏的 MAX() | 可以 |
| SS、FF、SF 三种类型 | 不支持 | 不支持 | 支持 |
| 连线上带标注的滞后量 | 没有, , 公式里一个裸的 +5 | 没有, , 公式里一个裸的 +5 | 有 |
| 关键路径 | 没有 | 没有 | 自动计算 |
| 每项任务的总浮动时间 | 没有 | 没有 | 自动计算 |
| 资源负荷与超配提醒 | 没有 | 没有 | 有 |
| 基准与偏差 | 手工复制一份列 | 手工复制一份列 | 保存并自动对比 |
| 插入一行后还正常 | 公式要重敲 | 基本正常 | 正常 |
| 对行排序后还正常 | 不正常, , 引用跟着位置走 | 不正常 | 正常 |
| 里程碑画成菱形 | 手工加标记系列 | 手工加规则 | 原生支持 |
这是一个具体的判断,不是一句贬低:堆积条形图是一张你在别处想好的进度的画像。十来项任务大致排成一条线的时候,这就够用了,电子表格正是对的工具。但那张表中间那几行,恰恰是你在进度例会上会被问到的东西,而这个文件一条都答不上来。
更快的路:在线搭好,再导出成 Excel
堆积条形图管用,但搭起来慢、改起来疼。如果你要的只是那个 Excel 文件而不是这堆杂活,先在 gantts.app 里把图搭好, , 免费、无需注册、无需下载。输入任务、拖动横条、连上依赖关系,关键路径自动算出来,然后一键导出 📊 Excel (.xlsx),也可以出 PowerPoint、PDF、PNG。
想要现成文件,可以直接用我们的 Excel 甘特图模板:任务表、堆积条形图设置、逆序坐标轴和日期格式都已经配好,填入自己的任务和日期,图就跟着更新。第一次做这种图,先读甘特图怎么做。
常见问题
Excel 有内置的甘特图类型吗?
没有。插入图表菜单里只有柱形图、条形图、折线图和饼图,没有一项叫"甘特图"。标准做法是用堆积条形图,把第一个数据系列设为无填充,剩下的横条就落在正确的开始位置上。微软自带的几个"甘特项目计划"模板,底下用的也是同一个技巧。
中文版 Excel 和 WPS 的公式要改写吗?
不用。中文版 Excel 的函数名仍是英文, , WORKDAY、NETWORKDAYS、MAX、COUNTIF 照写, , 参数之间用半角逗号分隔,不是分号。WPS Office 在这一点上与 Excel 完全一致,本文所有公式都可以原样粘贴。
为什么我的横条长度不对?
两个常见原因。一是偏移量或工期列还是日期格式,把它们改成"常规"或"数值"即可。二是把工作日直接当成了横条长度:图表横轴是含周末和节假日的自然日历,所以横条长度要写 =C2-B2+1,而不是引用工作日那一列。
法定节假日和调休怎么处理?
把节假日日期列在一个区域里(例如 H2:H5),所有 WORKDAY 和 NETWORKDAYS 都带上这个参数。调休上班的周六 WORKDAY 处理不了,只能把该任务的工作日数手工减一天,或者干脆换用会算工作日历的排程工具。
为什么任务顺序是反的?
Excel 默认把表格第一行画在图表最下方。选中纵轴,设置坐标轴格式 → 坐标轴选项 → 勾选"逆序类别",第一项任务就回到顶部;同一面板里把"横坐标轴交叉"设为"最大分类",日期轴会留在上方。
Excel 能显示完成百分比吗?
能,但要用三个系列而不是四个。加一列完成百分比,再加两列辅助:"已完成"=横条长度×完成百分比,"剩余"=横条长度×(1−完成百分比),按"开始、已完成、剩余"作图并丢掉原来的长度系列。把进度系列直接叠在工期之上是常见错误, , 那会让每条横条都比真实工期更长。
任务延误时 Excel 甘特图会自动更新吗?
只有在每项任务的开始日期是引用前置任务结束日期的公式时才会,例如 =WORKDAY(C2,1,$H$2:$H$5),此时改动能沿单条链往下传。它处理不了有两个前置任务的情况,也表达不了开始-开始或完成-完成;而且坐标轴边界是写死的序列号,日期一旦超出项目原定结束日,横条会跑出图外且没有任何提示。
有现成的 Excel 模板吗?
有。我们的模板可下载为 XLSX,辅助列、逆序坐标轴和日期格式都已经设好,填入任务即可。也可以在 gantts.app 里搭好之后一键导出成 Excel,省掉全部堆积条形图的设置工作。
延伸阅读
本文也提供英文版本。