174 lines
7.2 KiB
Python
174 lines
7.2 KiB
Python
import ezdxf
|
|
from ezdxf.math import Vec3
|
|
import os
|
|
|
|
# ==============================================================================
|
|
# 1. STYLE & GEOMETRY DEFINITIONS
|
|
# Based on the analysis of the existing DXF file.
|
|
# ==============================================================================
|
|
|
|
# --- Column widths for the two types of tables ---
|
|
TABLE_1_COL_WIDTHS = [15.0, 30.0, 55.0, 10.0, 30.0, 10.0, 10.0, 20.0] # Simplified for main part
|
|
TABLE_2_COL_WIDTHS = [15.0, 30.0, 55.0, 10.0, 30.0, 10.0, 10.0, 20.0, 47.5, 15.0, 5.0, 25.0, 20.0, 30.0, 5.0, 10.0, 5.0, 15.0, 10.0, 10.0, 5.0, 5.0, 20.0]
|
|
|
|
# --- Row Heights ---
|
|
DEFAULT_ROW_HEIGHT = 8.0
|
|
HEADER_ROW_1_HEIGHT = 5.5
|
|
HEADER_ROW_2_HEIGHT = 6.5
|
|
|
|
# --- Text Style Templates (Height, dX, dY) ---
|
|
# These represent common text placements within a cell.
|
|
STYLES = {
|
|
# Generic styles from content analysis
|
|
"id_number": (3.50, 5.00, 5.50),
|
|
"part_code": (3.00, 1.50, 5.50),
|
|
"name_zh": (3.50, 2.00, 4.00),
|
|
"name_en": (2.00, 2.00, 7.00),
|
|
"spec": (3.00, 18.50, 4.00),
|
|
"quantity": (3.00, 4.00, 5.50),
|
|
"material": (3.00, 8.50, 5.50),
|
|
"single_weight": (3.00, 2.00, 6.00),
|
|
"total_weight": (3.00, 2.00, 6.00),
|
|
"remark": (3.00, 3.50, 3.50),
|
|
|
|
# Specific Header Styles (from Header Analysis)
|
|
"header_zh": (3.50, 4.50, 5.50),
|
|
"header_en": (2.00, 2.00, 4.75),
|
|
"header_mass_zh": (3.50, 2.50, 5.60),
|
|
"header_mass_en": (2.00, 8.30, 4.80),
|
|
}
|
|
|
|
# ==============================================================================
|
|
# 2. DATA TO BE INSERTED
|
|
# This would typically come from an Excel file or database.
|
|
# ==============================================================================
|
|
|
|
TABLE_1_DATA = [
|
|
# Each item in the list is a row.
|
|
# Each item in the row is a cell, containing a list of (style, text) tuples.
|
|
[ [("id_number", "21")], [("part_code", "N-123-A")], [("name_zh", "新盖板"), ("name_en", "NEW COVER")], [("quantity", "2")], [("material", "S30408")], [("single_weight", "5.1")], [("total_weight", "10.2")], [("remark", "自定义")] ],
|
|
[ [("id_number", "22")], [("part_code", "N-456-B")], [("name_zh", "新支架"), ("name_en", "NEW BRACKET"), ("spec", "M20x150")], [("quantity", "4")], [("material", "Q235B")], [("single_weight", "2.0")], [("total_weight", "8.0")], [("remark", "")] ],
|
|
]
|
|
|
|
TABLE_2_HEADER_DATA = [
|
|
# Simplified header based on analysis
|
|
[ [("header_zh", "件 号")], [("header_zh", "图号或标准号")], [("header_zh", "名 称")], [("header_zh", "数量")], [("header_zh", "材 料")], [("header_mass_zh", "质量"), ("header_mass_en", "MASS(kg)")], [], [("header_zh", "备 注")] ],
|
|
[ [("header_en", "PARTS .NO.")], [("header_en", "DWG NO. OR STD. NO.")], [("header_en", "PARTS. NAME.")], [("header_en", "QTY.")], [("header_en", "MAT'L'")], [], [], [("header_en", "REMARKS")] ],
|
|
]
|
|
|
|
# ==============================================================================
|
|
# 3. DRAWING LOGIC
|
|
# ==============================================================================
|
|
|
|
def draw_table(msp, start_pos, col_widths, data_rows):
|
|
"""
|
|
Draws a complete table with grid lines and text.
|
|
|
|
Args:
|
|
msp: Modelspace object from ezdxf.
|
|
start_pos: Vec3 top-left starting position for the table.
|
|
col_widths: List of column widths.
|
|
data_rows: List of rows, where each row is a list of cells.
|
|
"""
|
|
current_pos = start_pos.copy()
|
|
col_x_coords = [current_pos.x]
|
|
for width in col_widths:
|
|
col_x_coords.append(col_x_coords[-1] + width)
|
|
|
|
# --- Draw Rows and Text ---
|
|
for row_data in data_rows:
|
|
row_y_top = current_pos.y
|
|
row_y_bottom = row_y_top - DEFAULT_ROW_HEIGHT
|
|
|
|
# Draw horizontal line for the row top
|
|
msp.add_line((current_pos.x, row_y_top), (col_x_coords[-1], row_y_top))
|
|
|
|
# Draw vertical lines and add text for each cell
|
|
for i, cell_data in enumerate(row_data):
|
|
cell_x_left = col_x_coords[i]
|
|
cell_x_right = col_x_coords[i+1]
|
|
|
|
# Draw left vertical line for the cell
|
|
msp.add_line((cell_x_left, row_y_top), (cell_x_left, row_y_bottom))
|
|
|
|
# Add text entities for the cell
|
|
for style_key, text_content in cell_data:
|
|
if not text_content: continue
|
|
|
|
style = STYLES.get(style_key)
|
|
if not style:
|
|
print(f"Warning: Style '{style_key}' not found. Skipping text.")
|
|
continue
|
|
|
|
text_height, dX, dY = style
|
|
|
|
# Calculate absolute position for the text
|
|
insert_pos = (cell_x_left + dX, row_y_top - dY)
|
|
|
|
msp.add_text(
|
|
text_content,
|
|
height=text_height,
|
|
dxfattribs={
|
|
"style": "Standard",
|
|
"insert": insert_pos,
|
|
}
|
|
)
|
|
|
|
# Draw the rightmost vertical line for the row
|
|
msp.add_line((col_x_coords[-1], row_y_top), (col_x_coords[-1], row_y_bottom))
|
|
|
|
# Move to the next row position by creating a new Vec3 object
|
|
current_pos = Vec3(current_pos.x, row_y_bottom)
|
|
|
|
# Draw the final bottom line of the table
|
|
msp.add_line((start_pos.x, current_pos.y), (col_x_coords[-1], current_pos.y))
|
|
|
|
# ==============================================================================
|
|
# 4. MAIN EXECUTION
|
|
# ==============================================================================
|
|
|
|
def main():
|
|
source_dxf_path = r"C:\Users\83500\久翌\CAD编辑同步excel\测试文件区\04_Test_Files\料表.dxf"
|
|
output_dxf_path = os.path.join(os.path.dirname(source_dxf_path), "料表_with_inserted_tables.dxf")
|
|
|
|
try:
|
|
doc = ezdxf.readfile(source_dxf_path)
|
|
msp = doc.modelspace()
|
|
except IOError:
|
|
print(f"Could not read DXF file: {source_dxf_path}")
|
|
return
|
|
except ezdxf.DXFStructureError:
|
|
print(f"Invalid or corrupted DXF file: {source_dxf_path}")
|
|
return
|
|
|
|
# --- Define where to start drawing the new tables ---
|
|
# We will use a fixed starting position below the existing content.
|
|
start_y = 150.0
|
|
start_x_1 = 266.0 # Aligns with the first table
|
|
start_x_2 = 700.0 # Place second table to the right
|
|
|
|
# --- Draw the first table ---
|
|
print("Drawing Table 1...")
|
|
table1_start_pos = Vec3(start_x_1, start_y)
|
|
# Combine header and data for drawing
|
|
# For this demo, we will create a small table with 2 data rows and a header
|
|
full_table_1_data = TABLE_1_DATA + TABLE_2_HEADER_DATA
|
|
draw_table(msp, table1_start_pos, TABLE_1_COL_WIDTHS, full_table_1_data)
|
|
|
|
# --- Draw the second table ---
|
|
print("Drawing Table 2...")
|
|
table2_start_pos = Vec3(start_x_2, start_y)
|
|
# Draw the same table again for demonstration
|
|
draw_table(msp, table2_start_pos, TABLE_1_COL_WIDTHS, full_table_1_data)
|
|
|
|
|
|
# --- Save the modified DXF ---
|
|
try:
|
|
doc.saveas(output_dxf_path)
|
|
print(f"Successfully saved modified DXF to: {output_dxf_path}")
|
|
except IOError:
|
|
print(f"Could not save DXF file to: {output_dxf_path}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|