我正在准备一个长表格(> 1 页,因此我使用包longtable
),设置为占据整个页面的 \textwidth。我的目标是制作信纸和 A4 大小的文档版本,但由于这些标准的大小不同,因此每个文档中的表格宽度都不同。
我希望将来能将表格扩展一些,并且我希望避免在 letter 和 A4 格式之间来回切换时手动调整相关长度参数。因此,我使用包tabularx
和(对于最右边的列)X
它提供的列类型,以便扩展表格的宽度。为了同时使用longtable
和的功能,tabularx
我使用了ltablex
为此目的而设计的包。
除此之外,表格环境每行最右边的单元格包含另一个表。这个内部表同样有一列类型X
。该ltablex
包重新定义了tabularx
环境,其结果是尝试将一个tabularx
环境嵌套在另一个环境中会产生错误:
! Extra alignment tab has been changed to \cr. <template> \endtemplate
在一个相关问题的答案大卫·卡莱尔 (David Carlisle) 给出了解决该问题的方法,定义了一个restoretx
恢复嵌套环境能力的命令tabularx
。
例如,这允许创建嵌套表,以便例如这个 mwe 编译并产生预期的结果:
\documentclass{article}
\usepackage{blindtext}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{tabularx}
%This block is from David Carlisle's code in the linked question
\makeatletter
\let\tx@\TX@endtabularx
\def\restoretx{\let\TX@endtabularx\tx@}
\makeatother
\usepackage{ltablex}
\newcommand{\innerTable}[2]{
{
\restoretx
\begin{tabularx}{\linewidth}{cX}
#1 & #2 \\
\end{tabularx}
}
}
\setlength{\parindent}{0cm}
\begin{document}
\begin{tabularx}{\linewidth}{cX}
test & \innerTable{test2}{\blindtext[1]} \\
test & \innerTable{test2}{\blindtext[1]} \\
[...about 40 copies of this row in total...]
test & \innerTable{test2}{\blindtext[1]} \\
test & \innerTable{test2}{\blindtext[1]} \\
\end{tabularx}
\end{document}
上面例子中的行数并非偶然:如果我们添加少量行的额外副本,test & \innerTable{test2}{\blindtext[1]} \\
那么文件仍会编译,但格式会严重破坏。在这种情况下,典型的页面现在看起来像
更糟糕的是,这种行为在运行过程中不一致:有时包含 40 行副本的文件可以正确编译,有时则不能。
查阅日志文件显示以下警告:
Package tabularx Warning: X Columns too narrow (table too wide) (tabularx) on input line 79.
我知道该tabularx
包(可能是该ltablex
包)会尝试通过某些迭代过程为每列计算X
适当的宽度,所以我认为这个警告意味着该包放弃了尝试寻找合适的宽度。
有没有办法迫使
ltablex
人们更加努力地寻找X
列的合适宽度,尽管要付出时间/内存的代价?(我实际使用的表比上面的长得多,大约有 170 行。)或者是否有另一种解决方法,仍然使用xtabular
带有列的嵌套环境X
?如果这无望(或者即使不是),可以使用哪些其他方法来达到相同的目的?
一些可能的解决方案——以及我最初拒绝它们的原因——我可能不得不接受它们:
另一个包编辑我尝试这样做,但编译完全失败,并报告内存问题:ltxtable
也结合了longtable
和tabularx
,其行为与 略有不同ltablex
。但是(无论是安装还是使用)这个包似乎都很特殊,包括默认情况下表代码需要放在单独的文件中,我希望尽可能避免这种情况。(我希望可以通过使用另一个包来规避这个特殊的限制。)! TeX capacity exceeded, sorry [text input levels=15].
也许我可以只测量和硬编码两种页面大小的相关长度,然后编写一个开关来检查页面大小以确定使用哪种大小——但这很笨拙,需要实际测量列大小(这是可行的, 尽管)。
这个问题顺便说一下,是相似的,但是 OP 的目的显然与我的有所不同,因为对此接受的答案(顺便说一下,也是由 David Carlisle 提出的)使用手动定义宽度的列,这正是我想要避免的。
编辑发布的答案建议使用xltabular
包而不是包ltablex
。这个包的优点很明显,就是不需要像\restoretx
上面的 mwe 中那样定义命令,但使用包并不能解决问题。事实上,它产生的输出格式基本上以同样的方式被破坏:
答案1
编辑。
该tabularx
包不适合用作其他表格中的嵌套表。一些测试表明,它可以嵌套多达 45 次,然后X
列宽的计算(在每个嵌套中)tabularx
不再起作用。
这是否可以解决是软件包作者要回答的问题。
同时可以通过两种方式来避免这种限制:
- 主表限制为 45 个嵌套
tabularx
表,然后重复主表(这似乎不是 OP 的选项) - 而是
tabularx
使用tabular*
并手动预先定义嵌套表中每列的宽度(这可能需要在检查第一次编译的结果后重新定义列宽之间的比率)
在这两种情况下,我都会改用ltablex
(它abularx
在很多方面重新定义,其中之一是,默认情况下,它会将X
列转换l
为小表的列)xltabular
。对于第二种情况,解决方案可以是:
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs, xltabular}
\newcommand{\innerTable}[2]%
{
\begin{tabular*}{\linewidth}{@{} >{\centering}p{\dimexpr0.12\linewidth-\tabcolsep}
p{\dimexpr0.88\linewidth-\tabcolsep} @{}}
#1 & #2
\end{tabular*}}
\setlength{\parindent}{0cm}
%---------------- show page layout. don't use in a real document!
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{red}}
%---------------------------------------------------------------%
\begin{document}
\setlength\tabcolsep{4pt}
\begin{xltabular}{\linewidth}{@{} cX @{}}
test & \innerTable{test 1}{\lipsum*[1]} \\ \addlinespace
test & \innerTable{test 2}{\lipsum*[2]} \\ \addlinespace
test & \innerTable{test 3}{\lipsum*[3]} \\ \addlinespace
test & \innerTable{test 4}{\lipsum*[4]} \\ \addlinespace
test & \innerTable{test 5}{\lipsum*[5]} \\ \addlinespace
test & \innerTable{test 6}{\lipsum*[6]} \\ \addlinespace
test & \innerTable{test 7}{\lipsum*[7]} \\ \addlinespace
test & \innerTable{test 8}{\lipsum*[8]} \\ \addlinespace
test & \innerTable{test 9}{\lipsum*[9]} \\ \addlinespace
test & \innerTable{test 10}{\lipsum*[10]} \\ \addlinespace
test & \innerTable{test 11}{\lipsum*[11]} \\ \addlinespace
test & \innerTable{test 12}{\lipsum*[12]} \\ \addlinespace
test & \innerTable{test 13}{\lipsum*[13]} \\ \addlinespace
test & \innerTable{test 14}{\lipsum*[14]} \\ \addlinespace
test & \innerTable{test 15}{\lipsum*[15]} \\ \addlinespace
test & \innerTable{test 16}{\lipsum*[16]} \\ \addlinespace
test & \innerTable{test 17}{\lipsum*[17]} \\ \addlinespace
test & \innerTable{test 18}{\lipsum*[18]} \\ \addlinespace
test & \innerTable{test 19}{\lipsum*[19]} \\ \addlinespace
test & \innerTable{test 20}{\lipsum*[20]} \\ \addlinespace
test & \innerTable{test 21}{\lipsum*[21]} \\ \addlinespace
test & \innerTable{test 22}{\lipsum*[22]} \\ \addlinespace
test & \innerTable{test 23}{\lipsum*[23]} \\ \addlinespace
test & \innerTable{test 24}{\lipsum*[24]} \\ \addlinespace
test & \innerTable{test 25}{\lipsum*[25]} \\ \addlinespace
test & \innerTable{test 26}{\lipsum*[26]} \\ \addlinespace
test & \innerTable{test 27}{\lipsum*[27]} \\ \addlinespace
test & \innerTable{test 28}{\lipsum*[28]} \\ \addlinespace
test & \innerTable{test 29}{\lipsum*[29]} \\ \addlinespace
test & \innerTable{test 30}{\lipsum*[30]} \\ \addlinespace
test & \innerTable{test 31}{\lipsum*[31]} \\ \addlinespace
test & \innerTable{test 32}{\lipsum*[32]} \\ \addlinespace
test & \innerTable{test 33}{\lipsum*[33]} \\ \addlinespace
test & \innerTable{test 34}{\lipsum*[34]} \\ \addlinespace
test & \innerTable{test 35}{\lipsum*[35]} \\ \addlinespace
test & \innerTable{test 36}{\lipsum*[36]} \\ \addlinespace
test & \innerTable{test 37}{\lipsum*[37]} \\ \addlinespace
test & \innerTable{test 38}{\lipsum*[38]} \\ \addlinespace
test & \innerTable{test 39}{\lipsum*[39]} \\ \addlinespace
test & \innerTable{test 40}{\lipsum*[40]} \\ \addlinespace
test & \innerTable{test 41}{\lipsum*[41]} \\ \addlinespace
test & \innerTable{test 42}{\lipsum*[42]} \\ \addlinespace
test & \innerTable{test 43}{\lipsum*[43]} \\ \addlinespace
test & \innerTable{test 44}{\lipsum*[44]} \\ \addlinespace
test & \innerTable{test 45}{\lipsum*[45]} \\ \addlinespace
test & \innerTable{test 46}{\lipsum*[46]} \\ \addlinespace
test & \innerTable{test 47}{\lipsum*[47]} \\ \addlinespace
test & \innerTable{test 48}{\lipsum*[48]} \\ \addlinespace
test & \innerTable{test 49}{\lipsum*[49]} \\ \addlinespace
test & \innerTable{test 50}{\lipsum*[50]} \\ \addlinespace
test & \innerTable{test 51}{\lipsum*[51]} \\ \addlinespace
test & \innerTable{test 52}{\lipsum*[52]} \\ \addlinespace
test & \innerTable{test 53}{\lipsum*[53]} \\ \addlinespace
test & \innerTable{test 54}{\lipsum*[54]} \\ \addlinespace
test & \innerTable{test 55}{\lipsum*[55]} \\ \addlinespace
test & \innerTable{test 56}{\lipsum*[56]} \\ \addlinespace
test & \innerTable{test 57}{\lipsum*[57]} \\ \addlinespace
test & \innerTable{test 58}{\lipsum*[58]} \\ \addlinespace
test & \innerTable{test 59}{\lipsum*[59]} \\ \addlinespace
test & \innerTable{test 60}{\lipsum*[60]} \\ \addlinespace
test & \innerTable{test 61}{\lipsum*[61]} \\ \addlinespace
test & \innerTable{test 62}{\lipsum*[62]} \\ \addlinespace
test & \innerTable{test 63}{\lipsum*[63]} \\ \addlinespace
test & \innerTable{test 64}{\lipsum*[64]} \\ \addlinespace
test & \innerTable{test 65}{\lipsum*[65]} \\ \addlinespace
test & \innerTable{test 66}{\lipsum*[66]} \\ \addlinespace
test & \innerTable{test 67}{\lipsum*[67]} \\ \addlinespace
test & \innerTable{test 68}{\lipsum*[68]} \\ \addlinespace
test & \innerTable{test 69}{\lipsum*[69]} \\ \addlinespace
test & \innerTable{test 70}{\lipsum*[70]} \\ \addlinespace
test & \innerTable{test 71}{\lipsum*[71]} \\ \addlinespace
test & \innerTable{test 72}{\lipsum*[72]} \\ \addlinespace
test & \innerTable{test 73}{\lipsum*[73]} \\ \addlinespace
test & \innerTable{test 74}{\lipsum*[74]} \\ \addlinespace
test & \innerTable{test 75}{\lipsum*[75]} \\ \addlinespace
test & \innerTable{test 76}{\lipsum*[76]} \\ \addlinespace
test & \innerTable{test 77}{\lipsum*[77]} \\ \addlinespace
test & \innerTable{test 78}{\lipsum*[78]} \\ \addlinespace
test & \innerTable{test 79}{\lipsum*[79]} \\ \addlinespace
test & \innerTable{test 80}{\lipsum*[80]} \\ \addlinespace
test & \innerTable{test 81}{\lipsum*[81]} \\ \addlinespace
test & \innerTable{test 82}{\lipsum*[82]} \\ \addlinespace
test & \innerTable{test 83}{\lipsum*[83]} \\ \addlinespace
test & \innerTable{test 84}{\lipsum*[84]} \\ \addlinespace
test & \innerTable{test 85}{\lipsum*[85]} \\ \addlinespace
test & \innerTable{test 86}{\lipsum*[86]} \\ \addlinespace
test & \innerTable{test 87}{\lipsum*[87]} \\ \addlinespace
test & \innerTable{test 88}{\lipsum*[88]} \\ \addlinespace
test & \innerTable{test 89}{\lipsum*[89]} \\ \addlinespace
test & \innerTable{test 80}{\lipsum*[90]} \\ \addlinespace
test & \innerTable{test 91}{\lipsum*[1]} \\ \addlinespace
test & \innerTable{test 92}{\lipsum*[1]} \\ \addlinespace
test & \innerTable{test 93}{\lipsum*[1]} \\ \addlinespace
test & \innerTable{test 94}{\lipsum*[1]} \\ \addlinespace
test & \innerTable{test 95}{\lipsum*[1]} \\ \addlinespace
test & \innerTable{test 96}{\lipsum*[96]} \\ \addlinespace
test & \innerTable{test 97}{\lipsum*[97]} \\ \addlinespace
test & \innerTable{test 98}{\lipsum*[98]} \\ \addlinespace
test & \innerTable{test 99}{\lipsum*[99]} \\ \addlinespace
test & \innerTable{test 100}{\lipsum*[100]}%\\ \addlinespace
test & \innerTable{test 101}{\lipsum*[101]} \\ \addlinespace
test & \innerTable{test 102}{\lipsum*[102]} \\ \addlinespace
test & \innerTable{test 103}{\lipsum*[103]} \\ \addlinespace
test & \innerTable{test 104}{\lipsum*[104]} \\ \addlinespace
test & \innerTable{test 105}{\lipsum*[105]}
\end{xltabular}
\end{document}
附录: 您可以通过将单元格内容对齐到其顶部来巧妙地避免所有问题。在这种情况下,不再需要表格嵌套,并且表格记录更短:
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs, xltabular}
\setlength{\parindent}{0cm}
%---------------- show page layout. don't use in a real document!
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{red}}
%---------------------------------------------------------------%
\begin{document}
\setlength\tabcolsep{4pt}
\begin{xltabular}{\linewidth}{@{} cc X @{}}
test & test 1 & \lipsum*[1] \\ \addlinespace
test & test 2 & \lipsum*[2] \\ \addlinespace
test & test 3 & \lipsum*[3] \\ \addlinespace
test & test 4 & \lipsum*[4] \\ \addlinespace
test & test 5 & \lipsum*[5] \\ \addlinespace
% etc
test & test 101 & \lipsum*[101] \\ \addlinespace
test & test 102 & \lipsum*[102] \\ \addlinespace
test & test 103 & \lipsum*[103] \\ \addlinespace
test & test 104 & \lipsum*[104] \\ \addlinespace
test & test 105 & \lipsum*[105] \\ \addlinespace
\end{xltabular}
\end{document}
这给出了(当然,在我看来)更漂亮,更专业的结果: