固定表格宽度(截取多余的)

本文介绍了一种使用CSS实现文本自动截断并以省略号显示的方法,适用于限制表格单元格内的文本长度,同时保持页面整洁。通过设置宽度和文本溢出样式,可以有效地控制文本显示,提升用户体验。
style="width:100px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap"


把上面这段CSS加到   <td><a href="Msg.aspx?MessageID...
你这段的TD里面。 width 就是你需要截取的长度。你自己自己调整。
这段CSS的意思是截取字符指定的长度,多余的用...表示。
当然,你可以给a标签加上title属性来让鼠标指上去显示完整的内容
import klayout.pya as pya from collections import defaultdict from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN from pptx.dml.color import RGBColor from pptx.enum.shapes import MSO_SHAPE import os import re import pandas as pd from PIL import Image, ImageDraw # 新增PIL库用于图像处理 # 算坐标,左下右上 def extract_coordinates(poly_str): # 使用正则表达式提取括号内的所有坐标 match = re.search(r'\(([\d\.,;]+)\)', poly_str) if not match: raise ValueError("无效的坐标字符串格式") # 分割坐标并转换为浮数列表 points = [] for pair in match.group(1).split(';'): if ',' in pair: x, y = map(float, pair.split(',')) points.append((x, y)) if not points: raise ValueError("未找到有效坐标") # 找到左下角坐标 (x最小, y最小) ll = min(points, key=lambda p: (p[0], p[1])) # 找到右上角坐标 (x最大, y最大) ur = max(points, key=lambda p: (p[0], p[1])) return ll[0], ll[1], ur[0], ur[1] def saveImageAll(lx, ly, rx, ry, output_image_name, lv): # 3. 更新视图 lv.update_content() # 设置导出区域(单位为微米) export_region = pya.DBox(lx - 1, ly - 1, rx + 1, ry + 1) # 左下x, 左下y, 右上x, 右上y for layer in lv.each_layer(): layer.visible = True # layer.frame_color = 0x00FFFF # 3. 更新视图 lv.update_content() # 设置视图区域 lv.zoom_box(export_region) # 导出图片 width = 2000 height = 1100 linewidth = 1 oversampling = -2 resolution = 0.0 # 使用正确的参数格式调用save_image_with_options lv.save_image_with_options(output_image_name, width, height, linewidth, oversampling, resolution, export_region, False) def saveImageByLayer(lx, ly, rx, ry, output_image_name, lv, target_layer_number, data_type): # 获取源图层信息 for layer in lv.each_layer(): source_layer = layer.source_layer print(f"层索引 {layer.layer_index()}: Layer Name={source_layer}") # 1. 首先将所有图层设置为不可见 for layer in lv.each_layer(): layer.visible = False # 2. 只将目标图层设置为可见 found = False for layer in lv.each_layer(): # 比较源层号而不是层索引 if layer.source_layer == target_layer_number and layer.source_datatype == data_type: layer.visible = True found = True layer.frame_color = 0xFF0000 # 红色轮廓 print(f"已设置层号 {target_layer_number} (索引 {layer.layer_index()}) 为可见") if not found: print(f"警告: 未找到层号 {target_layer_number}") # 3. 更新视图 lv.update_content() # 设置导出区域(单位为微米)- 添加缓冲区 buffer = 1000 # 微米单位的缓冲区大小 export_region = pya.DBox(lx - buffer, ly - buffer, rx + buffer, ry + buffer) # 设置视图区域 lv.zoom_box(export_region) # 导出图片 width = 4000 height = 2200 linewidth = 1 oversampling = -2 resolution = 0.0 # 导出原始图像 lv.save_image_with_options(output_image_name, width, height, linewidth, oversampling, resolution, export_region, False) print(f"原始图片已导出到: {output_image_name}") '''===== 新增部分:添加黄色矩形边框 =====''' try: # 打开导出的图片 img = Image.open(output_image_name) draw = ImageDraw.Draw(img) # 计算图片坐标比例 img_width, img_height = img.size region_width = (rx + buffer) - (lx - buffer) region_height = (ry + buffer) - (ly - buffer) # 将布局坐标转换为图片坐标 def layout_to_image_coords(layout_x, layout_y): """将布局坐标转换为图片像素坐标""" x_percent = (layout_x - (lx - buffer)) / region_width y_percent = 1.0 - ((layout_y - (ly - buffer)) / region_height) # 反转Y轴 img_x = int(x_percent * img_width) img_y = int(y_percent * img_height) return img_x, img_y # 计算矩形边界在图片上的坐标 top_left = layout_to_image_coords(lx, ry) # 左上角 (lx, ry) bottom_right = layout_to_image_coords(rx, ly) # 右下角 (rx, ly) # 绘制黄色矩形边框 (RGB: 255, 255, 0) border_width = 5 # 边框宽度(像素) draw.rectangle( [top_left, bottom_right], outline=(0, 255, 255), # 黄色 width=border_width ) # 保存处理后的图片 img.save(output_image_name) print(f"已添加黄色矩形边框: {output_image_name}") except Exception as e: print(f"添加黄色矩形边框时出错: {str(e)}") '''===============================''' # 加载DRC报告数据库 report_db = pya.ReportDatabase().load("NEPTUNEZ_FIN.out") # 确保文件存在 gds_path = "NEPTUNEZ_FIN.oas" if not os.path.exists(gds_path): raise FileNotFoundError(f"GDS文件未找到: {gds_path}") # 创建LayoutView实例 lv = pya.LayoutView() # 加载GDS文件 lv.load_layout(gds_path) # 获取当前布局和顶层单元 lv.max_hier() # Show full hierarchy lv.zoom_fit() # Zoom to fit content # 存储所有类别的数据结构 all_categories = [] category_counter = defaultdict(int) # 用于统计每个类别的总项目数 # 遍历所有cell和item for item_cell in report_db.each_cell(): layer_name = item_cell.name() cell_category_data = defaultdict(lambda: {"description": "", "items": []}) for item_id in item_cell.each_item(): category = report_db.category_by_id(item_id.category_id()) cat_name = category.name() # 更新全局类别计数器 category_counter[cat_name] += 1 # 只保存每个类别的前三个项目 if len(cell_category_data[cat_name]["items"]) >= 3: continue # 保存类别描述 if not cell_category_data[cat_name]["description"]: cell_category_data[cat_name]["description"] = category.description # 收集当前项目的所有值 item_values = [str(item_value) for item_value in item_id.each_value()] cell_category_data[cat_name]["items"].append(item_values) # 收集这个cell的所有类别数据 for cat_name, data in cell_category_data.items(): if data["items"]: category_entry = { "layerName": layer_name, "ruleName": cat_name, "description": data["description"], "items": list(data["items"]) } all_categories.append(category_entry) # 创建PPT演示文稿 prs = Presentation() # 读取Excel文件 file_path = 'layerInfo202509051508.xlsx' df = pd.read_excel(file_path) # 创建以layerName为键的字典 layer_dict = {} for _, row in df.iterrows(): layer_name = row['Layer Name'] layer_dict[layer_name] = { 'GDS': row['GDS'], 'Data Type': row['Data Type'], } # 为每个违规类别创建详细页 for category in all_categories: slide = prs.slides.add_slide(prs.slide_layouts[6]) # === 规则描述处理 === full_description = category["description"] rule_name = category["ruleName"] prefix_rule_name = rule_name.split('_', 1)[0] total_errors = category_counter[rule_name] # 规则描述超过50字符时显示省略号 if len(full_description) > 300: display_description = full_description[:300] + "..." else: display_description = full_description # === 将完整描述添加到备注 === notes_slide = slide.notes_slide notes_text_frame = notes_slide.notes_text_frame notes_text_frame.text = f"规则完整描述:\n{full_description}" # === 左侧区域:规则描述 === left_start = Inches(0.2) left_width = Inches(2.8) # 左侧区域宽度 # 添加标题(图层+规则名) title_box = slide.shapes.add_textbox(left_start, Inches(-0.2), left_width, Inches(1)) title_frame = title_box.text_frame title_para = title_frame.add_paragraph() title_para.text = f"{category['layerName']} - {category['ruleName']}" title_para.font.size = Pt(24) title_para.font.bold = True title_para.alignment = PP_ALIGN.LEFT # 添加规则描述区域 desc_box = slide.shapes.add_textbox(left_start, Inches(0.8), left_width, Inches(2.0)) desc_frame = desc_box.text_frame desc_frame.word_wrap = True # 添加描述文本 desc_para = desc_frame.add_paragraph() desc_para.text = "Rule Detail:" desc_para.font.size = Pt(14) desc_para.font.bold = True desc_content = desc_frame.add_paragraph() desc_content.text = display_description desc_content.font.size = Pt(10) desc_content.font.color.rgb = RGBColor(70, 70, 70) # ===== Zensemi Comment文本框 ===== risk_box_y = Inches(0.8) + Inches(2.0) + Inches(0.2) risk_box = slide.shapes.add_textbox(left_start, risk_box_y, left_width, Inches(0.8)) risk_frame = risk_box.text_frame risk_frame.word_wrap = True # 标题 risk_title = risk_frame.add_paragraph() risk_title.text = "Zensemi comment:" risk_title.font.size = Pt(14) risk_title.font.bold = True risk_title.font.color.rgb = RGBColor(200, 0, 0) # ===== 评论(CTM Comment)文本框 ===== comment_box_y = risk_box_y + Inches(0.8) + Inches(0.5) comment_box = slide.shapes.add_textbox(left_start, comment_box_y, left_width, Inches(1.5)) comment_frame = comment_box.text_frame comment_frame.word_wrap = True # 标题 comment_title = comment_frame.add_paragraph() comment_title.text = "CTM comment(Please input \u2713):" comment_title.font.size = Pt(14) comment_title.font.bold = True comment_title.font.color.rgb = RGBColor(0, 100, 200) # 内容(占位符) comment_content = comment_frame.add_paragraph() comment_content.text = "#Waive:" comment_content.font.size = Pt(12) comment_content.font.color.rgb = RGBColor(100, 100, 100) # 内容(占位符) comment_content = comment_frame.add_paragraph() comment_content.text = "#Update GDS:" comment_content.font.size = Pt(12) comment_content.font.color.rgb = RGBColor(100, 100, 100) # ===== remark文本框 ===== remark_box_y = comment_box_y + Inches(0.8) + Inches(0.5) remark_box = slide.shapes.add_textbox(left_start, remark_box_y, left_width, Inches(1.5)) remark_frame = remark_box.text_frame remark_frame.word_wrap = True remark_content = remark_frame.add_paragraph() remark_content.text = "Remark:" remark_content.font.size = Pt(14) remark_content.font.bold = True remark_content.font.color.rgb = RGBColor(34, 139, 34) # === 右侧区域:违规表格 === right_start = left_start + left_width + Inches(0.3) right_width = Inches(5.0) # 表格标题 table_title = slide.shapes.add_textbox(right_start, Inches(0.1), right_width, Inches(0.2)) title_frame = table_title.text_frame title_para = title_frame.add_paragraph() title_para.font.size = Pt(14) title_para.font.bold = True title_para.alignment = PP_ALIGN.CENTER # 添加违规项目表格 if category["items"]: num_items = len(category["items"]) rows = num_items + 1 cols = 4 # 创建表格 table_shape = slide.shapes.add_table( rows, cols, right_start, Inches(1.0), right_width, Inches(1.0 * rows) ) table = table_shape.table # 设置表头样式 headers = ["#", f"Error[{total_errors}]", "ALL", f"{prefix_rule_name}"] for col in range(cols): cell = table.cell(0, col) cell.text = headers[col] cell.fill.solid() cell.fill.fore_color.rgb = RGBColor(59, 89, 152) cell.text_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255) cell.text_frame.paragraphs[0].font.bold = True # 设置列宽比例 if col == 0: table.columns[col].width = Inches(0.3) elif col == 1: table.columns[col].width = Inches(1.6) else: table.columns[col].width = Inches(2.4) # 缩短表头行高 table.rows[0].height = Inches(0.5) # 填充数据行 for row_idx in range(1, rows): # 序号列 table.cell(row_idx, 0).text = str(row_idx) table.cell(row_idx, 0).text_frame.paragraphs[0].font.bold = True table.cell(row_idx, 0).text_frame.paragraphs[0].font.size = Pt(12) # 违规信息列 violation_info = category["items"][row_idx - 1] coordinates = extract_coordinates(''.join(violation_info)) saveImageAll(coordinates[0], coordinates[1], coordinates[2], coordinates[3], f"screenshots/{category['ruleName']}.png", lv) if prefix_rule_name in layer_dict: info = layer_dict[prefix_rule_name] saveImageByLayer(coordinates[0], coordinates[1], coordinates[2], coordinates[3], f"screenshots/{category['ruleName']}_{info['GDS']}_{info['Data Type']}.png", lv, info['GDS'], info['Data Type']) info_cell = table.cell(row_idx, 1) info_cell.text = "\n".join(violation_info) info_cell.text_frame.paragraphs[0].font.size = Pt(11) info_cell.text_frame.word_wrap = True # 调整行高 table.rows[row_idx].height = Inches(2.0) # 截图列 for col_idx in [2, 3]: cell = table.cell(row_idx, col_idx) cell.text = "" # 计算单元格位置 cell_left = table_shape.left + sum([table.columns[c].width for c in range(col_idx)]) cell_top = table_shape.top + sum([table.rows[r].height for r in range(row_idx)]) # 图片尺寸 pic_width = table.columns[col_idx].width - Inches(0.1) pic_height = table.rows[row_idx].height - Inches(0.1) # 添加图片占位符 placeholder = slide.shapes.add_shape( MSO_SHAPE.ROUNDED_RECTANGLE, cell_left + Inches(0.05), cell_top + Inches(0.05), pic_width, pic_height ) placeholder.fill.solid() placeholder.fill.fore_color.rgb = RGBColor(230, 230, 230) screenshot_path = f"1.png" if col_idx == 2: screenshot_path = f"screenshots/{category['ruleName']}.png" elif col_idx == 3: if prefix_rule_name in layer_dict: info = layer_dict[prefix_rule_name] screenshot_path = f"screenshots/{category['ruleName']}_{info['GDS']}_{info['Data Type']}.png" # 添加截图 if os.path.exists(screenshot_path): slide.shapes.add_picture( screenshot_path, cell_left + Inches(0.05), cell_top + Inches(0.05), width=pic_width, height=pic_height ) # 保存PPT文件 prs.save("DRC_Violation_Report_With_Risk_Comment.pptx") print("PPT报告生成完成") Rule Detail 字符串为: Rule File Pathname: /home/user/asd/TO_check/Pre_TO/DRC/dsa/DRC_results/.batchdrc/xx.rule Rule File Title: Design rule file. 我不想要Rule File Pathname: /home/user/asd/TO_check/Pre_TO/DRC/dsa/DRC_results/.batchdrc/xx.这部分内容,其它保留
09-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值