目前存在这一个问题,其他问题修改好了问题出现在 如果我插入平级的标题,插入在研究の実施体制之后 一个我是哈哈哈哈哈标题,如果研究の実施体制有子标题,这样顺序都变了。原来的段落格式不改变
还有一个问题 目录序号为什么没有重新排序呀 import aspose.words as aw
lic = aw.License()
lic_path = os.path.join(settings.BASE_PATH, "core/Aspose.Total.Product.Family.lic")
lic.set_license(lic_path)
# 加载现有文档
doc = aw.Document("/Users/dip/Desktop/111.docx")
deleting = False
# 初始化文档构建器
builder = aw.DocumentBuilder(doc)
numbering_pattern = r"^\s*[\d\.]+\s*" # 匹配以数字和点开头的部分
# 处理删除操作
deleted_ids = ["研究分担者"] # 需要删除的标题列表
for para in doc.get_child_nodes(aw.NodeType.PARAGRAPH, True):
text_without_numbering = re.sub(numbering_pattern, "", para.get_text()).strip()
is_title = para.as_paragraph().paragraph_format.outline_level in [
0,
1,
2,
3,
4,
5,
]
if deleting:
# 如果在删除状态下,遇到下一个标题则停止删除
if is_title:
deleting = False # 退出删除模式
else:
para.remove() # 删除当前段落
# 如果找到要删除的标题,开始删除状态
if is_title and text_without_numbering in deleted_ids:
para.remove() # 删除该标题
deleting = True # 开始删除模式
# 处理添加操作
added_titles_with_parents = [
{
"parent_id": 0,
"parent": "研究の実施体制",
"added_title": "1.2 研究代wwwwww表者111",
"is_child": True,
"level": 2,
},
{
"parent_id": 0,
"parent": "研究の実施体制",
"added_title": "2 我是哈哈哈哈哈",
"is_child": False,
"level": 1,
},
]
# 创建标题字典,方便查找父级标题
title_dict = {
re.sub(numbering_pattern, "", para.get_text()).strip(): para
for para in doc.get_child_nodes(aw.NodeType.PARAGRAPH, True)
}
# 添加新的标题
for item in added_titles_with_parents:
parent_title = item["parent"]
added_title = item["added_title"]
level = item["level"]
if parent_title in title_dict:
parent_para = title_dict[parent_title]
parent_para = parent_para.as_paragraph()
# 将光标移动到父级标题之后
builder.move_to(parent_para)
# 插入一个新的段落
new_paragraph = builder.insert_paragraph().as_paragraph()
# 从父级标题中获取样式
parent_style = parent_para.paragraph_format # 父级段落的样式
parent_font = parent_para.runs[0].font # 获取字体
new_paragraph.paragraph_format.style = doc.styles.get_by_style_identifier(
getattr(aw.StyleIdentifier, f"HEADING{level}")
)
# 添加新的文本
new_run = aw.Run(doc)
new_run.font.name = parent_font.name
new_run.font.size = parent_font.size
new_run.text = added_title
new_paragraph.append_child(new_run)
# # 更新文档中的所有域,这包括目录、交叉引用、页码等
# 处理修改操作
modifications = [{"original": "研究代表者", "modified": "1.1 研究代表者111"}]
# 修改标题
for mod in modifications:
original = mod["original"]
modified = mod["modified"]
if original in title_dict:
para = title_dict[original]
para = para.as_paragraph()
# 清除原有文本但保持段落结构
para.runs.clear() # 清除段落中的所有 `Run`
# 使用 `insert_after()` 添加新文本
new_run = aw.Run(doc, modified) # 创建新的 `Run`
para.insert_after(new_run, para.first_child) # 插入到第一个子节点之后
# 可选:更新自动编号的列表
# 保存修改后的文档
doc.update_fields()
doc.update_table_layout() # 可选:在目录有图形内容时可使用
doc.update_list_labels() # 可选:更新自动编号的列表
doc.save("modified_document.docx")
以上问题已经解决 最后剩下的问题是怎么对文档目录序号进行排序。如果我插入2个序号为2的需要进行重新排序。
import aspose.words as aw
lic = aw.License()
lic_path = os.path.join(settings.BASE_PATH, "core/Aspose.Total.Product.Family.lic")
lic.set_license(lic_path)
# 加载现有文档
doc = aw.Document("/Users/dip/Desktop/111.docx")
deleting = False
# 初始化文档构建器
builder = aw.DocumentBuilder(doc)
numbering_pattern = r"^\s*[\d\.]+\s*" # 匹配以数字和点开头的部分
# 处理删除操作
deleted_ids = ["研究分担者"] # 需要删除的标题列表
for para in doc.get_child_nodes(aw.NodeType.PARAGRAPH, True):
text_without_numbering = re.sub(numbering_pattern, "", para.get_text()).strip()
is_title = para.as_paragraph().paragraph_format.outline_level in [
0,
1,
2,
3,
4,
5,
]
if deleting:
# 如果在删除状态下,遇到下一个标题则停止删除
if is_title:
deleting = False # 退出删除模式
else:
para.remove() # 删除当前段落
# 如果找到要删除的标题,开始删除状态
if is_title and text_without_numbering in deleted_ids:
para.remove() # 删除该标题
deleting = True # 开始删除模式
# 处理添加操作
added_titles_with_parents = [
{
"parent_id": 0,
"parent": "研究の実施体制",
"added_title": "1.2 研究代wwwwww表者111",
"is_child": True,
"level": 2,
},
{
"parent_id": 0,
"parent": "研究の実施体制",
"added_title": "2 我是哈哈哈哈哈",
"is_child": False,
"level": 1,
},
]
# 创建标题字典,方便查找父级标题
title_dict = {
re.sub(numbering_pattern, "", para.get_text()).strip(): para
for para in doc.get_child_nodes(aw.NodeType.PARAGRAPH, True)
}
# 添加新的标题
for item in added_titles_with_parents:
parent_title = item["parent"]
added_title = item["added_title"]
level = item["level"]
if parent_title in title_dict:
parent_para = title_dict[parent_title]
parent_para = parent_para.as_paragraph()
builder.move_to(parent_para) # 将光标移动到父级标题
if item["is_child"]:
# 在父级标题后直接插入
new_paragraph = builder.insert_paragraph()
else:
# 找到父级标题的最后一个非标题段落
current_para = parent_para
# 遍历直到最后一个与父级标题相关的段落
while (
current_para.next_sibling
and current_para.next_sibling.as_paragraph().paragraph_format.outline_level
> parent_para.as_paragraph().paragraph_format.outline_level
):
current_para = current_para.next_sibling
# 移动到最后一个相关段落
builder.move_to(current_para)
new_paragraph = builder.insert_paragraph()
# 设置新标题的样式和文本
new_paragraph.paragraph_format.style = doc.styles.get_by_style_identifier(
getattr(aw.StyleIdentifier, f"HEADING{level}")
)
# 设置字体和文本
new_run = aw.Run(doc)
parent_font = parent_para.runs[0].font # 从父级标题获取字体
new_run.font.name = parent_font.name
new_run.font.size = parent_font.size
new_run.text = added_title
new_paragraph.append_child(new_run)
# # 更新文档中的所有域,这包括目录、交叉引用、页码等
# 处理修改操作
modifications = [{"original": "研究代表者", "modified": "1.1 研究代表者111"}]
# 修改标题
for mod in modifications:
original = mod["original"]
modified = mod["modified"]
if original in title_dict:
para = title_dict[original]
para = para.as_paragraph()
# 清除原有文本但保持段落结构
para.runs.clear() # 清除段落中的所有 `Run`
# 使用 `insert_after()` 添加新文本
new_run = aw.Run(doc, modified) # 创建新的 `Run`
para.insert_after(new_run, para.first_child) # 插入到第一个子节点之后
doc.save("modified_document.docx")
@Tiaohh 在这种情况下,最好的选择是使用列表。我修改了您的文档,并添加了一些列表作为示例。
111_modified.docx (51.4 KB)
另外,请这样更新您的代码:
if item["is_child"]:
# 在父级标题后直接插入
new_paragraph = builder.insert_paragraph()
builder.list_format.list_indent()
else:
# 找到父级标题的最后一个非标题段落
current_para = parent_para
# 遍历直到最后一个与父级标题相关的段落
while (
current_para.next_sibling
and current_para.next_sibling.as_paragraph().paragraph_format.outline_level
> parent_para.as_paragraph().paragraph_format.outline_level
):
current_para = current_para.next_sibling
# 移动到最后一个相关段落
builder.move_to(current_para)
new_paragraph = builder.insert_paragraph()
builder.list_format.list = parent_para.as_paragraph().list_format.list
列表会自动更新编号。
如果需要使用 "DocumentBuilder "插入其他文本,请通过以下方式重置列表格式:
builder.list_format.list = None
你好帮我看一下我的代码报错没有 table_header.parent_node.insert_after(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: ‘NoneType’ object has no attribute ‘insert_after’
需求是我只需要在当前标题下面的段落内容之后插入表格信息
async def generate_docx_with_result_laikai(
header_list: list,
table_list: list,
save_path,
template_path,
):
logger.info(f"header list内容: {header_list}")
logger.info(f"table list内容: {table_list}")
base_file = template_path
clear_save_path = base_file
doc_main = aw.Document(clear_save_path)
paragraphs = doc_main.get_child_nodes(aw.NodeType.PARAGRAPH, True)
for para in paragraphs:
para = para.as_paragraph()
para_content = para.to_string(aw.SaveFormat.TEXT)
para_content = para_content.replace("\r", "")
para_content = (
para_content.strip()
) # 特殊地方,发现目录中有这个符号,暂时不知道符号是干啥的
if (
para_content in header_list or para_content.capitalize() in header_list
): # 如果当前段落中有写作内容,那么找到内容,找到生成的结果
print(para_content)
table_header = aw.Paragraph(doc_main)
table_header.paragraph_format.style_identifier = aw.StyleIdentifier.NORMAL
table_header.paragraph_format.alignment = aw.ParagraphAlignment.CENTER
try:
if para_content in ["APPENDICES", "REFERENCES"]:
para_content = para_content.capitalize()
idx_num = header_list.index(para_content)
# 获取header对应的table
num_tables = len(table_list[idx_num])
logger.info(f"当前表格长度:{num_tables}")
for _index, info in enumerate(table_list[idx_num]):
table_id = info.get("id", "")
is_header_and_footer = info.get("is_header_and_footer", "")
logger.warning(f"table_id in table list:{table_id}")
aw.Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.rtf")
).save(os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx"))
# 判断是否需要页眉页脚 False为删除页眉页脚
if not is_header_and_footer:
document = Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
for section in document.sections:
section.footer.is_linked_to_previous = True
section.header.is_linked_to_previous = True
document.save(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
# doc_rtf = aw.Document(
# os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
# )
# builder = aw.DocumentBuilder(doc_rtf)
# 判断分页是否续表
# builder.row_format.heading_format = False
# doc_rtf.save(os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx"))
_doc = aw.Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
_tables = _doc.get_child_nodes(aw.NodeType.TABLE, True)
_tables = [t for t in _tables]
# 删除表格第一行内容
logger.info(f"插入表格: {table_id}")
for (
table
) in _tables: # 将table 信息反向的插入到word文件中。TODO 表格美化
table_clone = table.as_table().clone(True)
imported_table = doc_main.import_node(table_clone, True)
logger.info(
f"imported table 节点类型: {imported_table.node_type}"
)
if imported_table.node_type == aw.NodeType.TABLE:
logger.info(f"imported table 节点是表格")
imported_table = imported_table.as_table()
imported_table.preferred_width = (
aw.tables.PreferredWidth.from_percent(100)
)
imported_table.first_row.remove()
for index, row in enumerate(imported_table.rows):
row = row.as_row()
for cell_index, cell in enumerate(row.cells):
cell = cell.as_cell()
cell.cell_format.vertical_alignment = (
aw.tables.CellVerticalAlignment.BOTTOM
)
for paragraph in cell.paragraphs:
paragraph = paragraph.as_paragraph()
# 居中对齐
for run in paragraph.runs:
run = run.as_run()
run.font.name = "Times New Roman" # 设置西文是新罗马字体
run.font.name_far_east = "宋体"
run.font.size = 8
# 在插入段落标题之后插入段落内容
table_header.parent_node.insert_after(
imported_table, table_header
)
if _index < num_tables - 1:
table_newline = aw.Paragraph(doc_main)
run = aw.Run(doc_main, "")
table_newline.append_child(run)
imported_table.parent_node.insert_before(
table_newline, imported_table
)
else:
logger.info(f"当前段落不需要插入表格内容")
# 插入result 模型输出结果 结果只插入一次,table插入完成后插入
# TODO 段落美化
except:
logger.warning(f"没有找到header{traceback.format_exc()}")
print("没有找到header", traceback.format_exc())
doc_main.save(save_path)
表格文件存在表格的标题怎么把文件信息插入到目标文件里吗
问题已解决 目前还有一个小问题
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
builder = aw.DocumentBuilder(doc_rtf)
# 判断分页是否续表
builder.row_format.heading_format = True
doc_rtf.save(os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx"))
_doc = aw.Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
_tables = _doc.get_child_nodes(aw.NodeType.TABLE, True)
_tables = [t for t in _tables]
# 删除表格第一行内容
logger.info(f"插入表格: {table_id}")
for table in _tables[
::-1
]: # 将table 信息反向的插入到word文件中。TODO 表格美化
table_clone = table.as_table().clone(True)
imported_table = doc_main.import_node(table_clone, True)
logger.info(
f"imported table 节点类型: {imported_table.node_type}"
)
if imported_table.node_type == aw.NodeType.TABLE:
logger.info(f"imported table 节点是表格")
imported_table = imported_table.as_table()
imported_table.preferred_width = (
aw.tables.PreferredWidth.from_percent(100)
)
for index, row in enumerate(imported_table.rows):
row = row.as_row()
if "Source:" in row.get_text():
for cell_index, cell in enumerate(row.cells):
cell = cell.as_cell()
cell.cell_format.vertical_alignment = (
aw.tables.CellVerticalAlignment.BOTTOM
)
for paragraph in cell.paragraphs:
paragraph = paragraph.as_paragraph()
# 居中对齐
for run in paragraph.runs:
run = run.as_run()
run.font.name = (
"Courier New" # 设置西文是新罗马字体
)
for index, row in enumerate(imported_table.rows):
row = row.as_row()
if “Source:” in row.get_text(): 怎么删除这一行数据呢
问题是如果我写到另一个文件里吗。没有分页,但是还是续表了
并且写入进去 怎么多了一个页脚呢 在页眉上面
async def generate_docx_with_result_laikai(
header_list: list,
table_list: list,
save_path,
template_path,
):
logger.info(f"header list内容: {header_list}")
logger.info(f"table list内容: {table_list}")
base_file = template_path
clear_save_path = base_file
doc_main = aw.Document(clear_save_path)
paragraphs = doc_main.get_child_nodes(aw.NodeType.PARAGRAPH, True)
for para in paragraphs:
para = para.as_paragraph()
para_content = para.to_string(aw.SaveFormat.TEXT)
para_content = para_content.replace("\r", "")
para_content = (
para_content.strip()
) # 特殊地方,发现目录中有这个符号,暂时不知道符号是干啥的
if (
para_content in header_list or para_content.capitalize() in header_list
): # 如果当前段落中有写作内容,那么找到内容,找到生成的结果
table_header = aw.Paragraph(doc_main)
table_header.paragraph_format.style_identifier = aw.StyleIdentifier.NORMAL
table_header.paragraph_format.alignment = aw.ParagraphAlignment.CENTER
try:
if para_content in ["APPENDICES", "REFERENCES"]:
para_content = para_content.capitalize()
idx_num = header_list.index(para_content)
# 获取header对应的table
num_tables = len(table_list[idx_num])
logger.info(f"当前表格长度:{num_tables}")
for _index, info in enumerate(table_list[idx_num]):
table_id = info.get("id", "")
is_header_and_footer = info.get("is_header_and_footer", "")
logger.warning(f"table_id in table list:{table_id}")
aw.Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.rtf")
).save(os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx"))
# 判断是否需要页眉页脚 False为删除页眉页脚
if not is_header_and_footer:
document = Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
for section in document.sections:
section.footer.is_linked_to_previous = True
section.header.is_linked_to_previous = True
document.save(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
doc_rtf = aw.Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
builder = aw.DocumentBuilder(doc_rtf)
# 判断分页是否续表
builder.row_format.heading_format = True
doc_rtf.save(os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx"))
_doc = aw.Document(
os.path.join(settings.UPLOAD_PATH, f"{table_id}.docx")
)
_tables = _doc.get_child_nodes(aw.NodeType.TABLE, True)
_tables = [t for t in _tables]
# 删除表格第一行内容
logger.info(f"插入表格: {table_id}")
for table in _tables[
::-1
]: # 将table 信息反向的插入到word文件中。TODO 表格美化
table_clone = table.as_table().clone(True)
imported_table = doc_main.import_node(table_clone, True)
logger.info(
f"imported table 节点类型: {imported_table.node_type}"
)
if imported_table.node_type == aw.NodeType.TABLE:
logger.info(f"imported table 节点是表格")
imported_table = imported_table.as_table()
imported_table.preferred_width = (
aw.tables.PreferredWidth.from_percent(100)
)
for index, row in enumerate(imported_table.rows):
row = row.as_row()
# if (
# "Source:" in row.get_text().strip()
# or not row.get_text().strip()
# ):
# row.remove()
for cell_index, cell in enumerate(row.cells):
cell = cell.as_cell()
cell.cell_format.vertical_alignment = (
aw.tables.CellVerticalAlignment.BOTTOM
)
for paragraph in cell.paragraphs:
paragraph = paragraph.as_paragraph()
# 居中对齐
for run in paragraph.runs:
run = run.as_run()
run.font.name = (
"Courier New" # 设置西文是新罗马字体
)
run.font.name_far_east = "宋体"
run.font.size = 8
# 在插入段落标题之后插入段落内容
para.parent_node.insert_after(imported_table, para)
# table_header.parent_node.insert_after(
# imported_table, table_header
# )
# if _index < num_tables - 1:
# table_newline = aw.Paragraph(doc_main)
# run = aw.Run(doc_main, "")
# table_newline.append_child(run)
# imported_table.parent_node.insert_before(
# table_newline, imported_table
# )
else:
logger.info(f"当前段落不需要插入表格内容")
# 插入result 模型输出结果 结果只插入一次,table插入完成后插入
# TODO 段落美化
except:
logger.warning(f"没有找到header{traceback.format_exc()}")
print("没有找到header", traceback.format_exc())
doc_main.save(save_path)
完整代码。 还需要 把表格插入在标题里的段落后面,目前是插入在段落前面了
你好 有进展了吗???????
@Tiaohh 我简化了代码,并在表前用页脚重现了问题。问题在于 Aspose.Words 的页眉页脚内容放置在表格之前,就像 DOM 模型中一样。因此,您需要以某种方式对"_tables "进行排序,以便在 HeaderFooter 对象之间移动表格。
怎么排序呢 ???? ,还有我怎么把表格插入到标题段落下面呢
有修改后的代码吗???????
还在看吗?????
?????