)Eja*dZddlmZmZddlmZmZmZmZm Z m Z m Z m Z m Z mZddlmZmZmZddlmZmZmZmZmZmZmZmZmZddlmZddlm Z m!Z!dd l"m#Z#m$Z$m%Z%m&Z&erdd l'm(Z(e!d Z)Gd dZ*GddZ+edGddZ,edGddZ-edGddZ. d%ddde/de/de/de/d e0e d!zd"e eezezd#dfd$Z1dS)&zF Usage documentation at: ) dataclassreplace) TYPE_CHECKINGAnyDictIteratorListLiteralOptionalSequenceTupleUnion) DeviceCMYK DeviceGray DeviceRGB) AlignCellBordersLayoutMethodReturnValueTableBordersLayoutTableCellFillModeTableHeadingsDisplay TableSpanVAlignWrapMode) FPDFException) CORE_FONTSFontFace) ImageTypeNumber NumberClassPadding)FPDFBOLD)emphasisc/eZdZdZ d:ddejdejddddeddd de j ddd d dd d d de e de e zde ezde ezdeee eze zezezezde ezdeee ezdededededeedede e zdeede deee ezezdeed ed!ee zezd"eef,d#Z d;d$e e d%eedee ezd&eed'd(f d)Zdd+ed1ed7ed'efd8Z!d'e"d-fd9Z#dS)?Tablez Object that `fpdf.fpdf.FPDF.table()` yields, used to build a table in the document. Detailed usage documentation: https://py-pdf.github.io/fpdf2/Tables.html CENTERMIDDLENTrFJUSTIFYr)alignv_alignborders_layoutcell_fill_colorcell_fill_mode col_widthsfirst_row_as_headings gutter_height gutter_widthheadings_style line_heightmarkdown text_alignwidthwrapmodepaddingouter_border_widthnum_heading_rowsrepeat_headingsmin_row_heightfpdfr#rowsr,r-r.r/r0r1r2r3r4r5r6r7r8r9r:r;r<r=r>r?c||_tj||_t j||_t j||_||_||_ tj||_ ||_ | |_ | |_| |_| |_| d|jznt%| |_||_||_||_||_t1||_t5j||_||_d|_g|_|t?j d|_!nt?j ||_!|jt j"t j#fvr|tIdd|_|jr4|J| t%|dz z| t%|dz zf|_%nd|_%|jdkrC|jdkr|j rtId|jdkr|j stIdn|j sd|_|D]}|&|dS) a. Args: fpdf (fpdf.FPDF): FPDF current instance rows: optional. Sequence of rows (iterable) of str to initiate the table cells with text content align (str, fpdf.enums.Align): optional, default to CENTER. Sets the table horizontal position relative to the page, when it's not using the full page width borders_layout (str, fpdf.enums.TableBordersLayout): optional, default to ALL. Control what cell borders are drawn cell_fill_color (float, tuple, fpdf.drawing.DeviceGray, fpdf.drawing.DeviceRGB): optional. Defines the cells background color cell_fill_mode (str, fpdf.enums.TableCellFillMode): optional. Defines which cells are filled with color in the background col_widths (float, tuple): optional. Sets column width. Can be a single number or a sequence of numbers. When `col_widths` is a single number, it is interpreted as a fixed column width in document units. When `col_widths` is provided as an array, the values are considered to be fractions of the full effective page width, meaning that `col_widths=(1, 1, 2)` is strictly equivalent to `col_widths=(25, 25, 50)`. first_row_as_headings (bool): optional, default to True. If False, the first row of the table is not styled differently from the others gutter_height (float): optional vertical space between rows gutter_width (float): optional horizontal space between columns headings_style (fpdf.fonts.FontFace): optional, default to bold. Defines the visual style of the top headings row: size, color, emphasis... line_height (number): optional. Defines how much vertical space a line of text will occupy markdown (bool): optional, default to False. Enable markdown interpretation of cells textual content text_align (str, fpdf.enums.Align, tuple): optional, default to JUSTIFY. Control text alignment inside cells. v_align (str, fpdf.enums.VAlign): optional, default to CENTER. Control vertical alignment of cells content width (number): optional. Sets the table width wrapmode (fpdf.enums.WrapMode): "WORD" for word based line wrapping (default), "CHAR" for character based line wrapping. padding (number, tuple, Padding): optional. Sets the cell padding. Can be a single number or a sequence of numbers, default:0 If padding for left and right ends up being non-zero then c_margin is ignored. outer_border_width (number): optional. Sets the width of the outer borders of the table. Only relevant when borders_layout is ALL or NO_HORIZONTAL_LINES. Otherwise, the border widths are controlled by FPDF.set_line_width() num_heading_rows (number): optional. Sets the number of heading rows, default value is 1. If this value is not 1, first_row_as_headings needs to be True if num_heading_rows>1 and False if num_heading_rows=0. For backwards compatibility, first_row_as_headings is used in case num_heading_rows is 1. repeat_headings (fpdf.enums.TableHeadingsDisplay): optional, indicates whether to print table headings on every page, default to 1. NrzTouter_border_width is only allowed when borders_layout is ALL or NO_HORIZONTAL_LINES)rrrz@first_row_as_headings needs to be False if num_heading_rows == 0z>first_row_as_headings needs to be True if num_heading_rows > 0)'_fpdfrcoerce _table_alignr_v_alignr_borders_layout_outer_border_width_cell_fill_colorr_cell_fill_mode _col_widths_first_row_as_headings_gutter_height _gutter_width_headings_style font_sizefloat _line_height _markdown _text_align_width _wrapmodeint_num_heading_rowsr_repeat_headings_min_row_height_initial_stylerAr"new_paddingALLNO_HORIZONTAL_LINES ValueError_outer_border_marginrow)selfr@rAr,r-r.r/r0r1r2r3r4r5r6r7r8r9r:r;r<r=r>r?rcs H,A#+)-"-"5A  5;M;M "% !!$%5!6!6 4 ;O L L-26! ?#KNNDMM#K00DM    "  2(   "- j(,D $  # /%111&8 9 9A =='9!:!:Q!>>)D % % )/D %  !Q & &%**t/J* V%))$2M) T . +)*&  C HHSMMMM  cellsstyle min_heightreturnRowc$|j|j|_t||||}|j||D]:}t |tr|jdi|%||;|S)z0Adds a row to the table. Returns a `Row` object.N)rir-rjr() r\rD font_facerlrAappend isinstancedictcell)rdrhrir-rjrcrrs rercz Table.rows   &"&*"6"6"8"8D $eWLLL   D$%%   4     rgc  |jrtd|jDnd|_|jH|jr/t |jt r|j|jz|_nj|jj|_nX|jrQt |jt r7|j|jz|jkrtd|jd|j|j|jjkr$td|jd|jj|j tj krtd|j dkr|jstd|jj}|z|jjp |jj}||jd d z}|t*vr)||jjvrt/d |d |jd |jj|jj|jj}}}|j tjkrE|jjt;|jz dz |j_|jj|j_n|j tjkrO|jj|jjz t;|jz |j_|jj|j_n0|jj|jjkr|jj|j_|jj|j dz}|g}|jrOtC|jD]:} ||"d| z }||j#z }|$|;tK|&|j'tPj)u} |jxj|j dz c_tU|j|j cxkrdkrKnnH|j+tYfdtC|j dzDtCtU|jD]!} | j-} |j+| } | rT|jj| z|jj.kr7||j_||j_||j_td| d| rb| r`| |j krU|jxj|j dz c_tC|j D] } |/| | |!| dkr|jxj|j0z c_|/| | |#||j_|jj|j_dS)zSThis is an internal method called by `fpdf.FPDF.table()` once the table is finishedc3$K|] }|jV dSN) cols_count).0rcs re zTable.render..s$CC#s~CCCCCCrgrNzInvalid value provided width=z$ should be a multiple of col_widths=z: effective page width is z>JUSTIFY is an invalid value for FPDF.table() 'align' parameterzcheadings_style must be provided to FPDF.table() if num_heading_rows>1 or first_row_as_headings=TrueUz Using font 'z' with emphasis 'zU' in table headings require the corresponding font style to be added using add_font()rCrc32K|]}|jVdSru)pagebreak_height)rwi rows_infos rerxzTable.render..s>aL1rgzThe row with index z4 is too high and cannot be rendered on a single page)cell_x_positions)1rAmax _cols_countrVrLrpr!rDepwrarFrJrYrPr%family font_familylowerrirrfontsrxyl_marginCwrRRr_marginrbrange_get_col_widthrOrolist_compute_rows_inforZrON_TOP_OF_EVERY_PAGElen_perform_page_break_if_need_besumr|page_break_trigger_render_table_rowrN)rdr%rfont_keyprev_xprev_y prev_l_marginxxrr}r>r| page_breakrow_idxr~s @rerenderz Table.rendersHLyW3CCCCCCCCVW ;  -Jt/?$M$M -".1AA "jn   *T-={"K"K $"22dkAA wDKwweieuww ; ' 'g ggW[WaWegg    ' 'P   !A % %'  y+4H#-4N 8N!<<>>HN,B,B3,K,KK:--($*BR2R2R'8v88888)- djlDJDW    ' '#':<% 2D2D#D"IDJ :.DJLL  %' ) ) tz22U4;5G5GG J  :.DJLL Z\TZ0 0 0"&*,DJ Z 4#>D2 6 6 6 6Q 6 6 6 6 6 J 5 5"4#9A#=>>    s49~~&& F FA(|< BB J JL#33dj6SSS & % &3 # a!aaa o !t7M2M2M  9! << $T%;<<G**!'*)9+ 1uu  33  " "1il4D E E E E, z* rgr}row_layout_info RowLayoutInforkwargsc <|j|}|jj}t|jD]N\}}t |t s|j|||f|j||d||j |O|j |j dS)N) row_heightcell_height_infor) rArDr enumeraterhrpCell_render_table_cellrSset_ylnheight) rdr}rrrrcrjrrs rerzTable._render_table_row6sil JL ++ GAtdD))  #D #  ,!0!1       J  Q     o,-----rgrrrrrrc |d}d} n)jdkr|jj}d} n |j}d} d} d} |j|} |||j} d}jp|j}t|ttfs||}|j }|J|j ||}|r"|jr||j}||jkrt#j||j}t#j|| j}t#j|j}jrt-jjn|j}j}|s| j}|s|j}| rd}n |J||}|j|| sh|J|jj}|jj}|| z}||z}t?fdtA| j!D}|j"#|tId| j!d|D||jtK|jtId| j!D| j& 'j()|j|||||r|j*nd|j+Q|j,J|jj-}|j.t_|j+|jj0}|t_|j,z}||j1dz }||j1dz}|dkr|j2|||||jz|j3kr}|j2|||||dkr|j2|||||jztK|jkr|j2|||||j.|j4r |jj|jj}}|jj-}j5s|d}n||j6z |j7z |z }|jxj|j8|d z zz c_|jxj|j6|d z zz c_|j9j4| |j8z |j:z |z |dj; }|j<|j6z|j7z|z}||z|jj=krd} |j>||j?r'd}|?|J|j@|} |tjBkr || z d z }n|tjCkr|| z }|jxj|z c_|J|jD|5|jjEd| |j?|jFd|d d d|jGtjItjJz|jK|j;d|\} }t| tsJt|t^sJ dddn #1swxYwY|jxj|zc_nd}| p| }!|J|!||fS)NTrFr) fill_colorc3*K|] \}}|u |VdSrur()rwr}row_cellrrs rerxz+Table._render_table_cell..s:!aX=M=M=M=M=M=Mrgc3K|]}|dV dSNrr(rwrrs rerxz+Table._render_table_cell..s'WWddFVFVFVFVFVWWrgc3K|]}|dV dSrr(rs rerxz+Table._render_table_cell..s'#P#P$t?OA?O?O?O?O#P#Prg)rcol_idxcol_posr=num_rows num_col_idx num_col_posrC)rhkeep_aspect_ratiolinkRIGHTTOP)rrtextmax_line_heightborderr,new_xnew_yfillr7outputr:r;rr()Mrowspanmerged_heightsrrArcolspanr,rUrprstrr\rKshould_fill_cellrJrrYrcombinerPrir;r"r]r^r-rGrDset_xrrnextrrhrHcell_style_getterrrrvoverride_cell_borderrdraw_cell_borderrrIrV line_widthset_line_widthrRrrblinerimgimg_fill_widthtopbottomleftimagerightrrendered_heightrset_xyrrendered_heightsrMB use_font_face multi_cellrSrTr PAGE_BREAKHEIGHTrWbool)"rdr}rrrrrrr cell_heightheight_query_onlypage_break_textpage_break_imagerc col_width img_heightr8ricell_mode_fillr;r-cell_xx1y1x2y2cell_idx_remember_linewidthrrcell_border_line_widthrdyactual_text_height do_pagebreaks" ` rerzTable._render_table_cellPsq(  #K $   \A  *9$,GK %  *1K %  il''1dl;;  Z34#3 *ucl33 '#AJ#   ->>q!DD  Dd3 DMMT-BMCCE t% % %$UD,@AAE  22  33/3|N'+dl+++, "kG $mG  )FF#///%a(F    !< ?***BBY k!B%.sy%9%9H$66WWci  .BWWWWW%)%; ^^ ##P#P#)#P#P#P P P #7&%dk22!!J38Bu//d "'3{...&*j&;# ))%0H*I*IJJJ Z(% ,,,$3A66$3A6666JOOBB333t|#t'777JOOBB333Avv BB7774<'3ty>>99 BB777 ))*=>>> 8# $:<qA&*Z%: "" k&9  '+->AWW JLLGL+AA+EE ELL JLLGK*@1*DD DLLJ$$gl*W]:=SS"&Y %E%+.!)) A~ ===#' J  a # # # 9% B&'333%5%Fq%I"fh&&%(::a?BB(($'99B JLLB LL$$$))%00 6 6/Dtz/D0 $($5$!!^,7:K:RR!^#0000,""/488888!+u555555' 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6* JLLB LLLK,@0@ &&&Z44sBX--X14X1rcr|j}|jJt|j|dz |jzz dt|jdzz }t |dz |jzd}|jst|||z z|zSt|jtr ||jz|zS|t|jkrtd|dzd|dzd}t|||zD]<}|j|t|jz } || |zz }||kr ||jz }=|S)zGets width of a column in a table, this excludes the outer gutter (outside the table) but includes the inner gutter between columns if the cell spans multiple columns.NrrCrz@Invalid .col_widths specified: missing width for table() column z on row ) rrVrRrOrbrrLrpr!rrarr) rdr}rrrvr9gutter_within_cellrk col_ratios rerzTable._get_col_width2s% {&&& $+  A~!33 4%1!4555 6  !'A+1C!CQGG NEJ$67:LLMM M d& 4 4 CT--0BB B D$%% % %iSTWXSXiibcfgbgii  q!g+&& 0 0A(+c$2B.C.CCI U* *IAvvT// rgc # Ki}i}t|jD]\}}||\}}|D]Q}||}|E|j|}t |t sJt ||jdz|j|<Rt|jD]B\} }t |t r(||| <t| dz| |j zD]} d|| <Ct|dkrtdg} g} g} g}|j 5t|jD]\}}g}g}|it|jD]\} }t |t s||| ||j\}}}|jr|}n|}|||| <|jdkr^| t%| ||j|p|||jk}||jz|jk}|r|rtd||||d}|r$t)|}|dkrt)|}|dkr|j}|jr||jkr|j}n&|jr||jkrt/|j}| || |j dddn #1swxYwYt3| d} d |jD}| D]}d}|j|jdz z}d}|D];}t)|||}|t/| |z }|||z }<||z|jkr|j||j|zzkr/|j|z |jz }|D]}|||<|j|z |z }|D]}||xx||jz z cc<t|jD]\}}t/| |||z}d|g} t|dz|| |zD]D} | | d |jzt/| | z|| zE|}!|| |z}"|dz} | |"krMt)|"| | | z}"|!|jt/| | z|| zz }!| dz } | |"kMt=| d|!||| VdS) Nr)rrz#Rowspan extends beyond end of table)rz:Heading includes rowspan beyond the number of heading rowsc|jSru)length)spans rez*Table._compute_rows_info..sT[rg)keycg|]}dS)rr()rw_s re z,Table._compute_rows_info..s(>(>(>q(>(>(>rg)rrA convert_spansrhrprrrrrrrrD_disable_writingrorrSrRowSpanLayoutInforYrrjr[rR max_rowspansortedrNr row_rangecontents_heightr)#rdactive_rowspansprev_row_in_colr}rcprior_rowspansrprev_rowrrrr rowspan_listrow_min_heights row_span_maxrdictated_heights img_heightsrr text_heightdictated_height is_headingspan_outside_headingrjrow_span_paddingr max_paddingassigned_heightassigned_paddingr;extrar merged_sizesr| pagebreak_rows# rerzTable._compute_rows_infoOs*,46 ** 2 2FAs.1.?.?.P.P +O^) V V*73'#>'2D%dD11111.5dDLSTDT.U.U.UHN7+$SY// 2 24dD))2),OA&"1q5!dl*:;;22-1**  2   1 $ $ EFF F13 (*"$ 35 Z ( ( * *> 5> 5#DI..= 5= 5302 +-  ''+++(33#7#7GAt%dD11! 261H1H#'#4 2I22.Az; *6*4*5.=$Q'*|a''$++- !1dlO4Qz &')?%? /04"/ \##)//@@@#**:6666 %& #6!$%5!6!6J!Q%(%5%5 ??!%!2J>A!CN22%(^ )A!D$888%*4+?%@%@ &&z222##CO4444{= 5> 5> 5> 5> 5> 5> 5> 5> 5> 5> 5> 5> 5> 5> 5> 5Bl0H0HIII )?(>DI(>(>(>  C CD!"K"1T[1_EO&' ^^%% 8 8!+/?/BCC 5);#<#<< $4Q$77  !11D4HHH'/DK+-B.%V,/B0!1B2.3c93B4!(5BBBBL "$(*.&* }!#,'  UO   &n+n+n+n+`. .).#8E?3 .  .  ....D  `5`5 `5 `5 `5  `5 #  `5# UO `5`5 tUE! "`5`5`5`5Dc%:YH_$=YYYYYYrgr'ceZdZdZ ddedeedeeezdee ddf dZ e de fd Z e de fd Zd ee e fdeee e fee ffd Zd dddddddddejf dedeeezdeeezdeedeedede de deee dfdeee zdededeffdZdS)rlz@Object that `Table.row()` yields, used to build a row in a tableNtablerir-rjrkcx||_g|_||_|rtj|n||_||_dSru)_tablerhrirrEr-rj)rdr)rir-rjs rerfz Row.__init__s? 79 ). 18Ev}W---g $rgc>td|jDS)Nc3<K|]}t|d|duVdS)rN)getattrrs rerxz!Row.cols_count..s3UU$74D,<==UUUUUUrg)rrhrds rervzRow.cols_counts!UU$*UUUUUUrgcdd|jD}t|rt|ndS)NcFh|]}t|t|jSr()rprrrs re z"Row.max_rowspan..s)OOO$ 48N8NOOOOrgr)rhrr)rdspanss rer zRow.max_rowspans2OO$*OOO ZZ.s5zzzQ.rgr czd}g}t|jD]\}}||tjkr^||}t |t st dt||jdz||<| dv| ||}t |t r,|jdkr!| dg|jdz zi}| D])\}} | |d| dkr| dz ||<*g} t|D]x\}}t |t r4|j dkr)t|||jzD]}|j dz ||<N|tjkr| |d||<y||_|| fS)Nrz4Invalid location for TableSpan.COL placeholder entryr)r)rrhrCOLrprrrrroextenditemsinsertrrROW) rdr prev_colrhr}rr prev_cellremaining_rowspansrvreverse_rowspanss rerzRow.convert_spanss24 ,, > >GAt|y}$$!(O !)T22'N#*)Y=NQR=R"S"S"Sh T"""" T"""dD))>dlQ.>.>LL$4eZdZUdZdZeed<eeee fed<eeee fed<ee ed<ee ed<e ed<eed <eed <eeeezezed <eeeefed <eed <ddedee ezddfdZdS)rz'Internal representation of a table cell) rr,r-rirrrrr;rrrr,r-rirrrrr;rrNrkc td)NzNot implemented yet)r@)rdrr,s rewritez Cell.writes!"7888rgru)r!r"r#r$ __slots__r__annotations__r rrrrrrrXrRr r"rrFr(rgrerrvs-- I III E#u*% &&&& eCK( )))) H  )  LLL LLL ehuo-7 8888 5c? #### 99#9hus{&;9t999999rgrcTeZdZUeed<eed<eeefed<eeed<dS)rrr|rrN)r!r"r#rRrHrrXr r(rgrerrsL MMM3:&&&&KrgrcDeZdZUeed<eed<eed<eed<defdZdS)rcolumnstartrr rkcFt|j|j|jzSru)rrLrr/s rer zRowSpanLayoutInfo.row_rangesTZdk!9:::rgN)r!r"r#rXrHrRrr r(rgrerrsX KKK JJJ KKK;5;;;;;;rgrNpdfr#rrrrr)rrrrkc |r|j}||g}|j} |j|z }|j|z }|| z}|| z}|| z}|| z}t |t r$t |drd}|r8|dkrdnd} ||dd|dd||z dd||z dd| n1|dkr+||dd|dd||z dd||z ddt |t rd |vr%||dd|dd |dd|dd d|vr%||dd|dd |dd|dd d |vr%||dd|dd |dd|dd d |vr%||dd|dd |dd|dd d |} | | |r||dSdS)aDraws a box using the provided style - private helper used by table for drawing the cell and table borders. Difference between this and rect() is that border can be defined as "L,R,T,B" to draw only some of the four borders; compatible with get_border(i,k) See Also: rect()LTRBrrfz.2f z re z re SLz m z l SrTN) rset_fill_colorrrrprset issupersetrojoin_out) rNrrrrrrprev_fill_colorslropss redraw_box_bordersr^s'. :&&&B A B B!GB!GB!GB!GB&#3v;;#9#9&#A#AMaKKSSS R'NNb'NN27(NNNb(NNN"NNOOOO 1 R'KKb'KK27(KKKb(KKKKLLL&#H &== II-FF"-FF.FFF".FFFF G G G &== II-FF"-FF.FFF".FFFF G G G &== II-FF"-FF.FFF".FFFF G G G &== II-FF"-FF.FFF".FFFF G G G  AHH , ?+++++,,rgru)2r$ dataclassesrrtypingrrrrr r r r r rdrawing_primitivesrrrenumsrrrrrrrrrerrorsrrrrutilrr r!r"r@r#r&r'rlrrrrRrr^r(rgreresd+*******                        BAAAAAAAAA                      "!!!!!''''''''999999999999!6222        DHHHHHHHHV $99999999@ $         $;;;;;;;;"AE9,9, 9, 9, 9,  9,  9, '$-  9,j09<=9, 9,9,9,9,9,9,rg