Laravel用DomPDF导出PDF时第二列图片拉伸,求两列均分宽度方案
Laravel中DomPDF打印列宽不均及图片拉伸问题修复
我在Laravel项目使用DomPDF实现打印功能时,整体效果正常,但出现两个问题:第二列图片被拉伸变形,且两列宽度无法均分。以下是问题相关代码、效果及修复方案:
原问题代码
原CSS代码
header { position: fixed; top: 5px; border: 3px solid gray; left: 0px; right: 0px; background-color: lightblue; height: 30px; text-align: center; color: #656262; } table { width: 100%; } .card { box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); max-width: 100%; height: 570px; margin-top: 90px; /* margin-left: 90px; */ text-align: center; font-family: arial; margin-right: 15px; border: 3px solid rgb(12, 12, 12); position: relative; } .image { width: 100%; max-height: 400px; } .price { color: grey; font-size: 22px; } .second { page-break-after: always; } .page { height: 100%; width: 100%; margin-right: 10px; } body { background-color: #f2f2f2; } .name { width: 82%; position: absolute; bottom: 100px; font-size: 25px; -webkit-border-radius: 28; -moz-border-radius: 28; border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: #2690ed; padding: 5px 20px 5px 20px; border: solid #ebe4e4 2px; text-decoration: none; font-weight: bolder; right: 50px; left: 15px; border: solid #ebe4e4 2px; text-decoration: none; } .price { display: block; float: left; margin-left: 10px; -webkit-border-radius: 28; -moz-border-radius: 28; border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: rgb(230, 83, 83); padding: 5px 20px 5px 20px; border: solid #ebe4e4 2px; text-decoration: none; position: absolute; bottom: 25px; right: 8px; } .quantity { margin-left: auto; width: 30%; -webkit-border-radius: 28; -moz-border-radius: 28; border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: rgb(243, 7, 7); padding: 5px 20px 5px 20px; border: solid #ebe4e4 2px; } .SKU { float: right; margin-right: 10px; background: #60e00a !important; background-image: -webkit-linear-gradient(top, #3498db, #2980b9); background-image: -moz-linear-gradient(top, #3498db, #2980b9); background-image: -ms-linear-gradient(top, #3498db, #2980b9); background-image: -o-linear-gradient(top, #3498db, #2980b9); background-image: linear-gradient(to bottom, #3498db, #2980b9); -webkit-border-radius: 28; -moz-border-radius: 28; border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; padding: 5px 20px 5px 20px; text-decoration: none; position: absolute; bottom: 25px; left: 8px; } .item-number { visibility: hidden; -webkit-border-radius: 28; -moz-border-radius: 28; border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: gray; padding: 5px 20px 5px 20px; border: solid #ebe4e4 2px; text-decoration: none; font-weight: bolder; }
原Blade视图代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> {{-- <link href="{{ asset('css/print.css') }}" rel="stylesheet"> --}} <link rel="stylesheet" href="{{ public_path('/css/print.css')}}"> <title>Unique Natural LLC</title> <style> </style> </head> <body> <header style="display:inline';overflow:inherit "> <p style="margin-top:2px;font-size: 25px;font-weight: bold">Unique Natural LLC</p> </header> <div class="page"> <table> @for ($i = 0; $i < count($products); $i += 2) <tbody> <tr> <td> <div class="card"> <img class="image" src="data:image/png;base64,{{ base64_encode(file_get_contents(public_path('images/' . $products[$i]->image))) }}"> {{-- <p class="quantity"> Out Of stock </p> --}} <P class="name">{{ $products[$i]->name }}</P> <p class="price">Price : {{ $products[$i]->price }} $</p> <p class="SKU"> SKU : {{ $products[$i]->SKU }} </p> </div> </td> <td> <div class="card second"> <img class="image" src="data:image/png;base64,{{ base64_encode(file_get_contents(public_path('images/' . $products[$i + 1]->image))) }}" alt="Denim Jeans"> <P class="name">{{ $products[$i + 1]->name }}</P> <p class="item-number"> Item Number: : {{ $products[$i + 1]->item_number }}</p> <p class="price">Price : {{ $products[$i + 1]->price }} $</p> <p class="SKU">SKU: {{ $products[$i + 1]->SKU }}</p> </div> </td> </tr> </tbody> @endfor </table> </div> </body> </html>
原输出效果

问题分析
- 列宽不均:表格
<td>未设置固定宽度,DomPDF会根据内容自动分配宽度,导致两列宽度不一致; - 图片拉伸:图片仅设置
width:100%和max-height,未限制宽高比,加上列宽异常,导致图片被拉伸; - 强制分页干扰:
.second类的page-break-after: always属性会强制第二列内容分页,进一步破坏列布局。
修复方案及修改后代码
修改后的CSS代码
header { position: fixed; top: 5px; border: 3px solid gray; left: 0px; right: 0px; background-color: lightblue; height: 30px; text-align: center; color: #656262; } table { width: 100%; border-collapse: collapse; /* 合并表格边框,消除额外间距 */ } table td { width: 50%; /* 强制两列各占50%宽度 */ padding: 0 8px; /* 列内添加内边距,避免内容拥挤 */ } .card { box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); width: 100%; /* 卡片占满列宽 */ height: 570px; margin-top: 90px; text-align: center; font-family: arial; border: 3px solid rgb(12, 12, 12); position: relative; box-sizing: border-box; /* 边框和内边距计入宽度,避免溢出 */ } .image { width: 100%; max-height: 400px; object-fit: contain; /* 保持图片原有比例,避免拉伸 */ object-position: center; /* 图片居中显示 */ } .price { color: grey; font-size: 22px; } .second { /* 移除强制分页属性,恢复正常列布局 */ } .page { height: 100%; width: 100%; padding: 0 10px; /* 用padding替代margin,避免页面边缘内容被截断 */ box-sizing: border-box; } body { background-color: #f2f2f2; margin: 0; /* 移除默认body边距 */ } .name { width: calc(100% - 30px); /* 动态计算宽度,适配不同列宽 */ position: absolute; bottom: 100px; font-size: 20px; border-radius: 28px; font-family: Arial; color: #ffffff; background: #2690ed; padding: 5px 20px; border: solid #ebe4e4 2px; font-weight: bolder; left: 15px; box-sizing: border-box; } .price { border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: rgb(230, 83, 83); padding: 5px 20px; border: solid #ebe4e4 2px; position: absolute; bottom: 25px; right: 8px; } .quantity { margin-left: auto; width: 30%; border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: rgb(243, 7, 7); padding: 5px 20px; border: solid #ebe4e4 2px; } .SKU { border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: #60e00a !important; padding: 5px 20px; position: absolute; bottom: 25px; left: 8px; } .item-number { visibility: hidden; border-radius: 28px; font-family: Arial; color: #ffffff; font-size: 20px; background: gray; padding: 5px 20px; border: solid #ebe4e4 2px; font-weight: bolder; }
修改后的Blade视图代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="{{ public_path('/css/print.css')}}"> <title>Unique Natural LLC</title> </head> <body> <header> <p style="margin-top:2px;font-size: 25px;font-weight: bold">Unique Natural LLC</p> </header> <div class="page"> <table> @for ($i = 0; $i < count($products); $i += 2) <tbody> <tr> <td> <div class="card"> <img class="image" src="data:image/png;base64,{{ base64_encode(file_get_contents(public_path('images/' . $products[$i]->image))) }}"> <P class="name">{{ $products[$i]->name }}</P> <p class="price">Price : {{ $products[$i]->price }} $</p> <p class="SKU"> SKU : {{ $products[$i]->SKU }} </p> </div> </td> @if(isset($products[$i+1])) <!-- 处理产品数量为奇数的情况,避免数组越界 --> <td> <div class="card second"> <img class="image" src="data:image/png;base64,{{ base64_encode(file_get_contents(public_path('images/' . $products[$i + 1]->image))) }}" alt="Product Image"> <P class="name">{{ $products[$i + 1]->name }}</P> <p class="item-number"> Item Number: : {{ $products[$i + 1]->item_number }}</p> <p class="price">Price : {{ $products[$i + 1]->price }} $</p> <p class="SKU">SKU: {{ $products[$i + 1]->SKU }}</p> </div> </td> @endif </tr> </tbody> @endfor </table> </div> </body> </html>
修复后效果说明
修改后,两列会严格各占页面可用宽度的50%,图片将保持原有比例居中显示,不会再出现拉伸变形的问题;同时新增了产品数量为奇数时的边界处理,避免数组越界报错。
内容的提问来源于stack exchange,提问作者Abdu4
相关产品推荐
相关产品推荐

