Flutter渲染HTML表格实现百分比+固定宽度列布局求助
可行解决方案
方案1:修改HTML模板(改动最小,优先推荐)
问题核心是默认HTML表格采用自动布局,Flutter侧渲染库未正确识别硬编码的列宽属性,你只需要给外层表格加强制固定布局属性,同时给所有列补充明确的宽度限制即可生效:
<table border="1" style="padding: 2px; margin: 5px; border: 1px solid red; border-radius: 5px; table-layout: fixed;" width="100%"> <tr> <!-- 前两列设为50%占比 --> <td style="width: 50%;"> <table width="100%"> <tr> <td><div align="left"><b>[offers_no]</b></div></td> <td><div align="right"><b>[offers_date]</b></div></td> </tr> </table> <div align="center"><i>[profsys_name] / [lamtypes_name] / [furnsys_name]</i></div> <table width="100%"> <tr> <td><div align="left"><b>[qty] шт.</b></div></td> <td><div align="right"><b>[sqr] м.кв.</b></div></td> </tr> </table> </td> <td style="width: 50%;"> <table width="100%"> <tr> <td><div align="left"><b>[offers_no]</b></div></td> <td><div align="right"><b>[offers_date]</b></div></td> </tr> </table> <div align="center"><i>[profsys_name] / [lamtypes_name] / [furnsys_name]</i></div> <table width="100%"> <tr> <td><div align="left"><b>[qty] шт.</b></div></td> <td><div align="right"><b>[sqr] м.кв.</b></div></td> </tr> </table> </td> <!-- 后两列强制固定100px宽,加最大最小宽度限制避免被拉伸 --> <td style="width: 100px; min-width: 100px; max-width: 100px;"> <a href="{report:report_get_offer_pdf}"> <center> <b>[zsum]</b> </center> </a> </td> <td style="width: 100px; min-width: 100px; max-width: 100px;"> <a href="{report:report_get_offer_pdf}"> <center> <b>[zsum]</b> </center> </a> </td> </tr> </table>
修改后两个主流渲染库都可以正确识别列宽。
方案2:自定义flutter_widget_from_html渲染逻辑(无需修改HTML模板)
如果不能改动HTML模板,可以通过自定义WidgetFactory拦截标签的渲染,手动处理宽度逻辑:
- 自定义WidgetFactory子类:
class CustomWidgetFactory extends WidgetFactory { @override Widget? buildTableCell(BuildMetadata meta, Widget child) { final widthAttr = meta.element.attributes['width']; if (widthAttr != null && int.tryParse(widthAttr) != null) { final width = int.parse(widthAttr).toDouble(); return SizedBox(width: width, child: child); } return super.buildTableCell(meta, child); } }
- 渲染时传入自定义工厂:
HtmlWidget( yourHtmlString, factoryBuilder: () => CustomWidgetFactory(), )
方案3:混合渲染(可控性最高)
如果上面两种方案都不满足需求,可以先解析HTML提取前两列的内容单独渲染,后两列直接用Flutter原生Container固定宽度实现,拼接成完整Row即可完全匹配原生布局效果。
内容的提问来源于stack exchange,提问作者Николай Невзоров
相关产品推荐
相关产品推荐

