civil-tools-v 0.0.1__py3-none-any.whl → 0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CivilTools/Const/CAD.py +2 -0
- CivilTools/Const/Concrete.py +144 -0
- CivilTools/Const/Steel.py +21 -0
- CivilTools/Const/__init__.py +3 -0
- CivilTools/DXFGenerator/BasicDXF.py +238 -1
- CivilTools/DXFGenerator/DetailDXF.py +324 -0
- CivilTools/DXFGenerator/DrawingAttribs.py +45 -0
- CivilTools/DXFGenerator/LayerManager.py +37 -0
- CivilTools/DXFGenerator/__init__.py +3 -0
- CivilTools/FigureGenerator/BasicPNGPlotter.py +28 -25
- CivilTools/FigureGenerator/BasicPltPlotter.py +115 -1
- CivilTools/FigureGenerator/SeismicReport/ShearMassRatio.py +73 -0
- CivilTools/FigureGenerator/SeismicReport/ShearMoment.py +71 -0
- CivilTools/FigureGenerator/SeismicReport/__init__.py +2 -0
- CivilTools/FigureGenerator/StairCalculationSheetPNGPlotter.py +2 -8
- CivilTools/ReportGenerator/BasicGenerator.py +109 -83
- CivilTools/ReportGenerator/DocParagraph.py +3 -5
- CivilTools/ReportGenerator/DocPicture.py +7 -8
- CivilTools/ReportGenerator/DocTable.py +11 -11
- CivilTools/ReportGenerator/SeismicReport.py +302 -143
- CivilTools/ReportGenerator/SeismicReportTemplate.py +523 -202
- CivilTools/ReportGenerator/StairCalculationReport.py +249 -185
- CivilTools/ReportGenerator/UtilFunctions.py +108 -104
- CivilTools/ReportGenerator/__init__.py +2 -2
- CivilTools/YDBLoader/BuildingDefine/Beam/Beam.py +12 -15
- CivilTools/YDBLoader/BuildingDefine/Column/Column.py +5 -5
- CivilTools/YDBLoader/BuildingDefine/ComponentType.py +1 -1
- CivilTools/YDBLoader/BuildingDefine/Geometry/Grid.py +8 -12
- CivilTools/YDBLoader/BuildingDefine/Geometry/Joint.py +11 -10
- CivilTools/YDBLoader/BuildingDefine/Geometry/StandFloor.py +1 -1
- CivilTools/YDBLoader/BuildingDefine/GlobalResult/BasicResult.py +44 -24
- CivilTools/YDBLoader/BuildingDefine/GlobalResult/SeismicResult.py +168 -54
- CivilTools/YDBLoader/BuildingDefine/Section/Section.py +26 -31
- CivilTools/YDBLoader/BuildingDefine/Section/ShapeEnum.py +9 -9
- CivilTools/YDBLoader/BuildingDefine/Slab/Slab.py +1 -1
- CivilTools/YDBLoader/BuildingDefine/StairPart/LoadDefine.py +16 -10
- CivilTools/YDBLoader/BuildingDefine/StairPart/StairComponent.py +41 -37
- CivilTools/YDBLoader/BuildingDefine/StairPart/StairPart.py +133 -78
- CivilTools/YDBLoader/SQLiteConnector/Connector.py +16 -8
- CivilTools/YDBLoader/SQLiteConnector/RowDataFactory.py +19 -17
- CivilTools/YDBLoader/SQLiteConnector/YDBTableName.py +31 -20
- CivilTools/YDBLoader/YDBLoader.py +128 -110
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/METADATA +88 -5
- civil_tools_v-0.0.3.dist-info/RECORD +60 -0
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/WHEEL +1 -1
- civil_tools_v-0.0.1.dist-info/RECORD +0 -50
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/LICENSE +0 -0
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
from ..BasicPltPlotter import SeismicPlotter, GetTicks
|
2
|
+
from typing import List
|
3
|
+
import numpy as np
|
4
|
+
import matplotlib.pyplot as plt
|
5
|
+
|
6
|
+
|
7
|
+
class ShearMomentPlotter(SeismicPlotter):
|
8
|
+
def __init__(self, floor_num=8, type="Shear", fig_num=2):
|
9
|
+
super().__init__(fig_num, floor_num)
|
10
|
+
self.__limit = None
|
11
|
+
if type.lower() == "shear":
|
12
|
+
self.type = "楼层剪力 kN"
|
13
|
+
elif type.lower() == "moment":
|
14
|
+
self.type = "倾覆力矩 MN·m"
|
15
|
+
else:
|
16
|
+
raise ValueError("Only shear or moment is supported for type.")
|
17
|
+
|
18
|
+
def set_data(
|
19
|
+
self,
|
20
|
+
wind_x: List[float],
|
21
|
+
wind_y: List[float],
|
22
|
+
seismic_x: List[float],
|
23
|
+
seismic_y: List[float],
|
24
|
+
):
|
25
|
+
# 验证数据长度
|
26
|
+
data_dict = {
|
27
|
+
"wind_x": wind_x,
|
28
|
+
"wind_y": wind_y,
|
29
|
+
"seismic_x": seismic_x,
|
30
|
+
"seismic_y": seismic_y,
|
31
|
+
}
|
32
|
+
for name, data_list in data_dict.items():
|
33
|
+
self._validate_list_length(data_list, name)
|
34
|
+
|
35
|
+
self._ax1_x = np.array(wind_x)
|
36
|
+
self._ax1_y = np.array(wind_y)
|
37
|
+
self._ax2_x = np.array(seismic_x)
|
38
|
+
self._ax2_y = np.array(seismic_y)
|
39
|
+
|
40
|
+
def plot(self):
|
41
|
+
if self.__limit:
|
42
|
+
self.__plot_limit()
|
43
|
+
kwargs_x = self.kwargs_x.copy()
|
44
|
+
kwargs_x["label"] = "X风"
|
45
|
+
kwargs_y = self.kwargs_y.copy()
|
46
|
+
kwargs_y["label"] = "Y风"
|
47
|
+
self.axes[0].plot(self._ax1_x, self._y_values, **kwargs_x)
|
48
|
+
self.axes[0].plot(self._ax1_y, self._y_values, **kwargs_y)
|
49
|
+
kwargs_x["label"] = "X小震"
|
50
|
+
kwargs_y["label"] = "Y小震"
|
51
|
+
self.axes[1].plot(self._ax2_x, self._y_values, **kwargs_x)
|
52
|
+
self.axes[1].plot(self._ax2_y, self._y_values, **kwargs_y)
|
53
|
+
self.__adjust_lim()
|
54
|
+
self.__add_titles()
|
55
|
+
|
56
|
+
def __adjust_lim(self):
|
57
|
+
xmaxs = [self._ax1_x.max(), self._ax2_x.max()]
|
58
|
+
for i in range(2):
|
59
|
+
self.axes[i].set_xlim(left=0, right=xmaxs[i] * 1.2)
|
60
|
+
self.axes[i].set_yticks(self._y_major_ticks)
|
61
|
+
self.axes[i].set_yticks(self._y_minor_ticks, minor=True)
|
62
|
+
x_ticks = GetTicks(xmaxs[i])
|
63
|
+
self.axes[i].set_xticks(x_ticks)
|
64
|
+
# self.axes[i].set_xticklabels([f"{i*100:.1f}%" for i in x_ticks])
|
65
|
+
|
66
|
+
def __add_titles(self):
|
67
|
+
self.axes[0].set_ylabel(self.y_label)
|
68
|
+
self.axes[0].set_xlabel(f"风下{self.type}")
|
69
|
+
self.axes[1].set_xlabel(f"小震下{self.type}")
|
70
|
+
self.axes[0].legend(framealpha=0, fontsize=12, loc=1)
|
71
|
+
self.axes[1].legend(framealpha=0, fontsize=12, loc=1)
|
@@ -1,5 +1,7 @@
|
|
1
|
+
import warnings
|
1
2
|
from enum import Enum
|
2
3
|
from docx import Document
|
4
|
+
from docx.document import Document as doc
|
3
5
|
from docx.shared import Inches, RGBColor, Pt, Cm
|
4
6
|
from docx.oxml.ns import qn, nsdecls
|
5
7
|
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT, WD_BREAK
|
@@ -10,36 +12,39 @@ from docx.enum.section import WD_ORIENTATION
|
|
10
12
|
from .DocParagraph import DocParagraph
|
11
13
|
from .DocPicture import DocPicture
|
12
14
|
from .DocTable import DocTable
|
13
|
-
from .UtilFunctions import set_cell_border
|
15
|
+
from .UtilFunctions import set_cell_border, analysis_sub_and_super_script
|
16
|
+
|
14
17
|
FONT_STR = "w:eastAsia"
|
15
18
|
|
19
|
+
|
16
20
|
class Page:
|
17
|
-
def __init__(self,width:float,height:float,is_landscape=False):
|
21
|
+
def __init__(self, width: float, height: float, is_landscape=False):
|
18
22
|
self._width = width
|
19
23
|
self._height = height
|
20
24
|
self.is_landscape = is_landscape
|
21
|
-
|
25
|
+
|
22
26
|
@property
|
23
27
|
def width(self):
|
24
28
|
return self._height if self.is_landscape else self._width
|
25
|
-
|
29
|
+
|
26
30
|
@property
|
27
31
|
def height(self):
|
28
32
|
return self._width if self.is_landscape else self._height
|
29
33
|
|
30
34
|
|
31
35
|
class PageSize(Enum):
|
32
|
-
A4 = Page(210,297)
|
33
|
-
A4_LANDSCAPE = Page(210,297,True)
|
34
|
-
A3 = Page(297,420)
|
35
|
-
A3_LANDSCAPE = Page(297,420,True)
|
36
|
-
|
37
|
-
|
36
|
+
A4 = Page(210, 297)
|
37
|
+
A4_LANDSCAPE = Page(210, 297, True)
|
38
|
+
A3 = Page(297, 420)
|
39
|
+
A3_LANDSCAPE = Page(297, 420, True)
|
40
|
+
|
41
|
+
|
38
42
|
class BasicGenerator:
|
39
43
|
|
40
44
|
def __init__(self):
|
41
45
|
self.mm_factor = 36000
|
42
46
|
self.doc = Document()
|
47
|
+
self.doc: doc
|
43
48
|
self.init_styles()
|
44
49
|
self.highlighted_color = 7
|
45
50
|
|
@@ -49,7 +54,7 @@ class BasicGenerator:
|
|
49
54
|
self.table_style = self.init_table_style(styles)
|
50
55
|
self.small_title_style = self.init_small_title_style(styles)
|
51
56
|
|
52
|
-
def init_body_style(self,styles):
|
57
|
+
def init_body_style(self, styles):
|
53
58
|
"""生成一个用于普通段落文字的body_style
|
54
59
|
|
55
60
|
Args:
|
@@ -58,15 +63,15 @@ class BasicGenerator:
|
|
58
63
|
Returns:
|
59
64
|
_type_: _description_
|
60
65
|
"""
|
61
|
-
body_style = styles[
|
66
|
+
body_style = styles["Body Text"]
|
67
|
+
body_style.font.name = "Times New Roman"
|
62
68
|
body_style.paragraph_format.first_line_indent = Inches(0.32)
|
63
69
|
body_style.paragraph_format.space_before = Pt(0)
|
64
70
|
body_style.paragraph_format.space_after = Pt(0)
|
65
|
-
body_style.
|
66
|
-
body_style._element.rPr.rFonts.set(qn(FONT_STR), '宋体')
|
71
|
+
body_style._element.rPr.rFonts.set(qn(FONT_STR), "宋体")
|
67
72
|
return body_style
|
68
73
|
|
69
|
-
def init_table_style(self,styles):
|
74
|
+
def init_table_style(self, styles):
|
70
75
|
"""生成一个用于表格内部段落文字的table_style
|
71
76
|
|
72
77
|
Args:
|
@@ -75,10 +80,10 @@ class BasicGenerator:
|
|
75
80
|
Returns:
|
76
81
|
_type_: _description_
|
77
82
|
"""
|
78
|
-
table_style = styles[
|
79
|
-
table_style.font.name =
|
83
|
+
table_style = styles["Normal"]
|
84
|
+
table_style.font.name = "Time New Roman"
|
80
85
|
table_style.font.size = Pt(10)
|
81
|
-
table_style._element.rPr.rFonts.set(qn(FONT_STR),
|
86
|
+
table_style._element.rPr.rFonts.set(qn(FONT_STR), "宋体")
|
82
87
|
table_style.paragraph_format.space_before = Pt(0)
|
83
88
|
table_style.paragraph_format.space_after = Pt(0)
|
84
89
|
return table_style
|
@@ -92,33 +97,32 @@ class BasicGenerator:
|
|
92
97
|
Returns:
|
93
98
|
_type_: _description_
|
94
99
|
"""
|
95
|
-
small_title_style = styles[
|
96
|
-
small_title_style.font.name =
|
97
|
-
small_title_style._element.rPr.rFonts.set(qn(FONT_STR),
|
100
|
+
small_title_style = styles["Body Text 2"]
|
101
|
+
small_title_style.font.name = "Times New Roman"
|
102
|
+
small_title_style._element.rPr.rFonts.set(qn(FONT_STR), "黑体")
|
98
103
|
small_title_style.paragraph_format.space_before = Pt(6)
|
99
104
|
small_title_style.paragraph_format.space_after = Pt(3)
|
100
105
|
small_title_style.paragraph_format.line_spacing = Pt(15)
|
101
106
|
return small_title_style
|
102
107
|
|
103
|
-
def change_paper_size(self, page_size:PageSize, column_num:int = 1):
|
108
|
+
def change_paper_size(self, page_size: PageSize, column_num: int = 1):
|
104
109
|
section = self.doc.sections[0]
|
105
110
|
section.page_width = int(page_size.value.width * self.mm_factor)
|
106
111
|
section.page_heigth = int(page_size.value.height * self.mm_factor)
|
107
112
|
if page_size.value.is_landscape:
|
108
|
-
section.orientation = WD_ORIENTATION.LANDSCAPE
|
113
|
+
section.orientation = WD_ORIENTATION.LANDSCAPE
|
109
114
|
sect_pr = section._sectPr
|
110
|
-
cols = sect_pr.xpath(
|
111
|
-
cols.set(qn(
|
112
|
-
|
113
|
-
def change_paper_margin(self, left:int, top:int, right:int, bottom:int):
|
114
|
-
"""改变页边距,单位为mm,按照左、上、右、下的顺序
|
115
|
-
"""
|
115
|
+
cols = sect_pr.xpath("./w:cols")[0]
|
116
|
+
cols.set(qn("w:num"), str(column_num))
|
117
|
+
|
118
|
+
def change_paper_margin(self, left: int, top: int, right: int, bottom: int):
|
119
|
+
"""改变页边距,单位为mm,按照左、上、右、下的顺序"""
|
116
120
|
section = self.doc.sections[0]
|
117
121
|
section.top_margin = int(self.mm_factor * top)
|
118
122
|
section.bottom_margin = int(self.mm_factor * bottom)
|
119
123
|
section.left_margin = int(self.mm_factor * left)
|
120
124
|
section.right_margin = int(self.mm_factor * right)
|
121
|
-
|
125
|
+
|
122
126
|
def add_big_title(self, context):
|
123
127
|
p = self.doc.add_paragraph(context)
|
124
128
|
run = p.runs[0]
|
@@ -126,7 +130,9 @@ class BasicGenerator:
|
|
126
130
|
run.font.bold = True
|
127
131
|
p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
128
132
|
|
129
|
-
def add_title(
|
133
|
+
def add_title(
|
134
|
+
self, title: DocParagraph, space_before: float = 0, space_after: float = 0
|
135
|
+
):
|
130
136
|
"""为了添加大纲等级而添加的函数,不需要大纲等级时不要使用
|
131
137
|
|
132
138
|
Args:
|
@@ -134,42 +140,45 @@ class BasicGenerator:
|
|
134
140
|
"""
|
135
141
|
p = self.doc.add_heading("", level=title.par_level)
|
136
142
|
run = p.add_run(title.context)
|
137
|
-
run.font.name =
|
138
|
-
run._element.rPr.rFonts.set(qn(
|
143
|
+
run.font.name = "Times New Roman"
|
144
|
+
run._element.rPr.rFonts.set(qn("w:eastAsia"), "宋体")
|
139
145
|
run.font.color.rgb = RGBColor(0, 0, 0)
|
140
146
|
par_format = p.paragraph_format
|
141
147
|
par_format.space_before = Pt(space_before)
|
142
148
|
par_format.space_after = Pt(space_after)
|
143
|
-
|
144
|
-
self.paragraph_format_double_check(p,title)
|
145
149
|
|
146
|
-
|
147
|
-
|
148
|
-
|
150
|
+
self.paragraph_format_double_check(p, title)
|
151
|
+
|
152
|
+
def add_paragraph(self, par: DocParagraph):
|
153
|
+
if par.context == None or par.context == "":
|
154
|
+
warnings.warn("This par has no context.")
|
155
|
+
return
|
156
|
+
if "{" in par.context:
|
157
|
+
a, b = analysis_sub_and_super_script(par.context)
|
149
158
|
if par.style != None:
|
150
|
-
p = self.doc.add_paragraph("",par.style)
|
159
|
+
p = self.doc.add_paragraph("", par.style)
|
151
160
|
else:
|
152
161
|
p = self.doc.add_paragraph()
|
153
|
-
self.add_context_with_sub_or_super(p,a,b)
|
154
|
-
elif par.style !=None:
|
155
|
-
p = self.doc.add_paragraph(par.context,par.style)
|
162
|
+
self.add_context_with_sub_or_super(p, a, b)
|
163
|
+
elif par.style != None:
|
164
|
+
p = self.doc.add_paragraph(par.context, par.style)
|
156
165
|
else:
|
157
166
|
p = self.doc.add_paragraph(par.context)
|
158
|
-
self.paragraph_format_double_check(p,par)
|
167
|
+
self.paragraph_format_double_check(p, par)
|
159
168
|
|
160
|
-
def add_context_with_sub_or_super(self, p,str_list,sub_or_super):
|
169
|
+
def add_context_with_sub_or_super(self, p, str_list, sub_or_super):
|
161
170
|
for i in range(len(str_list)):
|
162
171
|
run = p.add_run(str_list[i])
|
163
|
-
run.font.name =
|
172
|
+
run.font.name = "Times New Roman"
|
164
173
|
if sub_or_super[i] == 1:
|
165
174
|
run.font.subscript = True
|
166
175
|
elif sub_or_super[i] == 2:
|
167
176
|
run.font.superscript = True
|
168
|
-
elif sub_or_super[i] ==3:
|
177
|
+
elif sub_or_super[i] == 3:
|
169
178
|
run.font.highlight_color = self.highlighted_color
|
170
179
|
run.font.size = Pt(11)
|
171
180
|
|
172
|
-
def paragraph_format_double_check(self,p,doc_par:DocParagraph):
|
181
|
+
def paragraph_format_double_check(self, p, doc_par: DocParagraph):
|
173
182
|
run = p.runs[0]
|
174
183
|
if doc_par.font_size != None:
|
175
184
|
run.font.size = Pt(doc_par.font_size)
|
@@ -183,85 +192,102 @@ class BasicGenerator:
|
|
183
192
|
if doc_par.font_size != None:
|
184
193
|
run.font.size = Pt(doc_par.font_size)
|
185
194
|
|
186
|
-
def add_table(self, my_table:DocTable):
|
195
|
+
def add_table(self, my_table: DocTable):
|
187
196
|
if my_table.title != None:
|
188
|
-
p = self.doc.add_paragraph(my_table.title,self.small_title_style)
|
197
|
+
p = self.doc.add_paragraph(my_table.title, self.small_title_style)
|
189
198
|
p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
190
|
-
table = self.doc.add_table(
|
199
|
+
table = self.doc.add_table(
|
200
|
+
rows=my_table.row_num, cols=my_table.column_num, style="Table Grid"
|
201
|
+
)
|
191
202
|
table.alignment = WD_TABLE_ALIGNMENT.CENTER
|
192
|
-
for
|
193
|
-
table.cell(i,j).merge(table.cell(k,p))
|
203
|
+
for i, j, k, p in my_table.merged_cells:
|
204
|
+
table.cell(i, j).merge(table.cell(k, p))
|
194
205
|
for i in range(my_table.row_num):
|
195
206
|
for j in range(my_table.column_num):
|
196
|
-
self.add_table_cell(table,my_table,i,j)
|
197
|
-
self.tab_bg_color(table,my_table.row_num,my_table.column_num)
|
198
|
-
|
199
|
-
def tab_bg_color(self, table, rows, cols, color_str=
|
207
|
+
self.add_table_cell(table, my_table, i, j)
|
208
|
+
self.tab_bg_color(table, my_table.row_num, my_table.column_num)
|
209
|
+
|
210
|
+
def tab_bg_color(self, table, rows, cols, color_str="CCCCCC"):
|
200
211
|
"""表格样式调整"""
|
201
212
|
shading_list = locals()
|
202
213
|
for i in range(cols):
|
203
|
-
shading_list[
|
204
|
-
r'<w:shd {} w:fill="{bgColor}"/>'.format(
|
205
|
-
|
214
|
+
shading_list["shading_elm_" + str(i)] = parse_xml(
|
215
|
+
r'<w:shd {} w:fill="{bgColor}"/>'.format(
|
216
|
+
nsdecls("w"), bgColor=color_str
|
217
|
+
)
|
218
|
+
)
|
219
|
+
table.rows[0].cells[i]._tc.get_or_add_tcPr().append(
|
220
|
+
shading_list["shading_elm_" + str(i)]
|
221
|
+
)
|
206
222
|
for i in range(rows):
|
207
|
-
shading_list[
|
208
|
-
r'<w:shd {} w:fill="{bgColor}"/>'.format(
|
209
|
-
|
223
|
+
shading_list["shading_elm_" + str(cols + i)] = parse_xml(
|
224
|
+
r'<w:shd {} w:fill="{bgColor}"/>'.format(
|
225
|
+
nsdecls("w"), bgColor=color_str
|
226
|
+
)
|
227
|
+
)
|
228
|
+
table.rows[i].cells[0]._tc.get_or_add_tcPr().append(
|
229
|
+
shading_list["shading_elm_" + str(cols + i)]
|
230
|
+
)
|
210
231
|
table_cells = table._cells
|
211
232
|
for i in range(rows):
|
212
|
-
table_row = table_cells[i * cols:i * cols + cols]
|
233
|
+
table_row = table_cells[i * cols : i * cols + cols]
|
213
234
|
for k in range(cols):
|
214
235
|
table_row[k].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
|
215
|
-
table_row[k].paragraphs[
|
236
|
+
table_row[k].paragraphs[
|
237
|
+
0
|
238
|
+
].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
|
216
239
|
if i == 0:
|
217
240
|
runs = table_row[k].paragraphs[0].runs
|
218
241
|
for m in range(len(runs)):
|
219
242
|
runs[m].bold = True
|
220
|
-
table.rows[i].height = Cm(0.7)
|
243
|
+
table.rows[i].height = Cm(0.7)
|
221
244
|
|
222
|
-
def add_table_cell(self, table, my_table:DocTable, i,j):
|
245
|
+
def add_table_cell(self, table, my_table: DocTable, i, j):
|
223
246
|
try:
|
224
|
-
cell = table.cell(i, j)
|
247
|
+
cell = table.cell(i, j)
|
225
248
|
_ = my_table.context[i][j]
|
226
249
|
except IndexError:
|
227
250
|
return
|
228
|
-
if
|
229
|
-
a,b = analysis_sub_and_super_script(my_table.context[i][j])
|
251
|
+
if "{" in my_table.context[i][j]:
|
252
|
+
a, b = analysis_sub_and_super_script(my_table.context[i][j])
|
230
253
|
p = cell.paragraphs[0]
|
231
|
-
self.add_context_with_sub_or_super(p,a,b)
|
254
|
+
self.add_context_with_sub_or_super(p, a, b)
|
232
255
|
else:
|
233
256
|
cell.text = my_table.context[i][j]
|
234
257
|
cell.paragraphs[0].style = self.table_style
|
235
258
|
p = cell.paragraphs[0]
|
236
259
|
p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
237
260
|
if my_table.no_grid:
|
238
|
-
set_cell_border(
|
239
|
-
|
240
|
-
|
241
|
-
|
261
|
+
set_cell_border(
|
262
|
+
cell,
|
263
|
+
top={"color": "#FFFFFF"},
|
264
|
+
bottom={"color": "#FFFFFF"},
|
265
|
+
start={"color": "#FFFFFF"},
|
266
|
+
end={"color": "#FFFFFF"},
|
267
|
+
)
|
242
268
|
if my_table.all_bold:
|
243
269
|
p.runs[0].font.bold = True
|
244
270
|
|
245
|
-
def add_picture(self,doc_picture:DocPicture):
|
246
|
-
self.doc.add_picture(
|
247
|
-
|
248
|
-
|
271
|
+
def add_picture(self, doc_picture: DocPicture):
|
272
|
+
self.doc.add_picture(
|
273
|
+
doc_picture.path_or_stream, width=Inches(doc_picture.width)
|
274
|
+
)
|
275
|
+
last_paragraph = self.doc.paragraphs[-1]
|
276
|
+
last_paragraph.alignment = 1
|
249
277
|
|
250
278
|
def add_blank_paragraph(self):
|
251
279
|
self.doc.add_paragraph()
|
252
280
|
|
253
281
|
def add_page_break(self):
|
254
|
-
if len(self.doc.paragraphs[-1].runs)>0:
|
282
|
+
if len(self.doc.paragraphs[-1].runs) > 0:
|
255
283
|
self.doc.paragraphs[-1].runs[0].add_break(WD_BREAK.PAGE)
|
256
284
|
else:
|
257
285
|
run = self.doc.paragraphs[-1].add_run("")
|
258
286
|
run.add_break(WD_BREAK.PAGE)
|
259
287
|
|
260
|
-
def save(self,path:str):
|
288
|
+
def save(self, path: str):
|
261
289
|
for _ in range(10):
|
262
290
|
try:
|
263
291
|
self.doc.save(path)
|
264
292
|
except Exception:
|
265
|
-
path = path.replace(".docx","1.docx")
|
266
|
-
|
267
|
-
|
293
|
+
path = path.replace(".docx", "1.docx")
|
@@ -1,5 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
1
|
class DocParagraph:
|
4
2
|
def init_attr(self):
|
5
3
|
self.style = None
|
@@ -11,7 +9,7 @@ class DocParagraph:
|
|
11
9
|
self.is_bold = None
|
12
10
|
self.alignment = None
|
13
11
|
self.par_level = None
|
14
|
-
|
15
|
-
def __init__(self,context):
|
12
|
+
|
13
|
+
def __init__(self, context):
|
16
14
|
self.context = context
|
17
|
-
self.init_attr()
|
15
|
+
self.init_attr()
|
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
1
|
class DocPicture:
|
3
|
-
|
4
|
-
def init_attr(self):
|
5
|
-
self.width =
|
6
|
-
|
7
|
-
def __init__(self,
|
8
|
-
self.
|
9
|
-
self.init_attr()
|
2
|
+
|
3
|
+
def init_attr(self, fig_num: int):
|
4
|
+
self.width = 2.36 * fig_num
|
5
|
+
|
6
|
+
def __init__(self, path_or_stream, fig_num: int = 1) -> None:
|
7
|
+
self.path_or_stream = path_or_stream
|
8
|
+
self.init_attr(fig_num)
|
@@ -1,30 +1,30 @@
|
|
1
1
|
from typing import List
|
2
2
|
|
3
|
+
|
3
4
|
class DocTable:
|
4
5
|
def init_content(self):
|
5
6
|
self.context = [["None"] * self.column_num for _ in range(self.row_num)]
|
6
7
|
self.merged_cells = set()
|
7
|
-
|
8
|
-
def __init__(self,row_num, column_num):
|
8
|
+
|
9
|
+
def __init__(self, row_num, column_num):
|
9
10
|
self.row_num = row_num
|
10
11
|
self.column_num = column_num
|
11
12
|
self.title = None
|
12
13
|
self.no_grid = False
|
13
14
|
self.all_bold = False
|
14
15
|
self.init_content()
|
15
|
-
|
16
|
+
|
16
17
|
def set_table_title(self, title):
|
17
|
-
self.title = title
|
18
|
-
|
19
|
-
|
18
|
+
self.title = title
|
19
|
+
|
20
20
|
def set_table_context(self, context):
|
21
21
|
if len(context) == self.row_num and len(context[0]) == self.column_num:
|
22
22
|
self.context = context
|
23
23
|
else:
|
24
24
|
raise ValueError("输入的内容行列数量不对")
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
def merge_cells(self, i, j, k, p):
|
27
|
+
"""从第i,j个cell merge到第k,p个cell"""
|
28
28
|
# 检查合并范围是否合法
|
29
29
|
if i < 0 or i >= self.row_num or j < 0 or j >= self.column_num:
|
30
30
|
raise ValueError("起始单元格超出表格范围")
|
@@ -32,10 +32,10 @@ class DocTable:
|
|
32
32
|
raise ValueError("结束单元格超出表格范围")
|
33
33
|
if i > k or (i == k and j > p):
|
34
34
|
raise ValueError("起始单元格必须在结束单元格之前")
|
35
|
-
|
36
|
-
|
35
|
+
|
36
|
+
# 检查是否与已合并的单元格冲突
|
37
37
|
for start_row, start_col, end_row, end_col in self.merged_cells:
|
38
38
|
if (i <= end_row and k > start_row) and (j <= end_col and p > start_col):
|
39
39
|
raise ValueError("合并范围与已合并的单元格冲突")
|
40
|
-
|
40
|
+
|
41
41
|
self.merged_cells.add((i, j, k, p))
|