改变 HTML 样式 Object.style.property=new style;

使用JavaScript改变HTML样式
本文介绍如何使用JavaScript通过HTML DOM更改HTML元素的样式。通过示例代码展示了如何修改元素的颜色、背景颜色及宽度等样式。

改变 HTML 样式

HTML DOM 允许 JavaScript 改变 HTML 元素的样式。如何改变 HTML 元素的样式呢?

语法:

Object.style.property=new style;

注意:Object是获取的元素对象,如通过document.getElementById("id")获取的元素。

基本属性表(property):

注意:该表只是一小部分CSS样式属性,其它样式也可以通过该方法设置和修改。

看看下面的代码:

改变 <p> 元素的样式,将颜色改为红色,字号改为20,背景颜色改为蓝:

<p id="pcon">Hello World!</p>
<script>
   var mychar = document.getElementById("pcon");
   mychar.style.color="red";
   mychar.style.fontSize="20";
   mychar.style.backgroundColor ="blue";
</script>

结果:

任务

现在我们来改变下HTML中元素的CSS样式:

1. 在右边编辑器中,第12行补充代码,修改h2标签的样式,将颜色设为红色。

2. 在右边编辑器中,第13行补充代码,修改h2标签的样式,将背景颜色设为灰色(#CCC)。

3. 在右边编辑器中,第14行补充代码,修改h2标签的样式,将宽设为300px。


<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>style样式</title>
</head>
<body>
  <h2 id="con">I love JavaScript</h2>
  <p> JavaScript使网页显示动态效果并实现与用户交互功能。</p>
  <script type="text/javascript">
    var mychar= document.getElementById("con");
    mychar.style.color="yellow";
    mychar.style.backgroundColor:"#CCC";
    mychar.style.width=300px;
  </script>
</body>
</html>



""" @Author : 王定雄 @Date : 2024-10-29 @Desc : 文本对象的数据结构的定义 """ import logging from kotei_omp.data.base_object import BaseObject from kotei_omp.data.layout import LayoutObject from kotei_omp.data.position import Position from kotei_omp.data.style import StyleObject from kotei_omp.data.coordinate import CoordinateObject from kotei_i18n.api import _ class CharObject(BaseObject): def __init__(self, char, style): self.char = char self.style = style def is_same(self, char_obj) -> bool: return self.char == char_obj.char and self.style == char_obj.style class TextObject(BaseObject): """文本对象""" def __init__(self): self._type = "text" self._text = '' # 完整内容 self._style = StyleObject() # 文本样式 self._layout = LayoutObject() # 文本布局对象 self._coordinate = CoordinateObject() # 文本的坐标 self._runs = [] # 文本片段对象列表,所有内容连起来就是完整内容 self._data_id = None # 唯一标识 self._position = Position() def to_dict(self): """ 将 TextObject 对象转换为字典 """ return { "type": self._type, "text": self._text, "style": self._style.to_dict(), # 调用 StyleObject 的 to_dict 方法 "layout": self._layout.to_dict(), # 调用 LayoutObject 的 to_dict 方法 "coordinate": self._coordinate.to_dict(), # 调用 CoordinateObject 的 to_dict 方法 "runs": [run.to_dict() for run in self._runs], # 递归转换 RunObject 列表 "data_id": self._data_id, "position": self._position.to_dict() } @classmethod def from_dict(cls, data): """ 从字典创建 TextObject 实例 """ obj = cls() obj._type = data.get("type", "text") obj._text = data.get("text", '') obj._style = StyleObject.from_dict(data.get("style", {})) # 恢复 StyleObject obj._layout = LayoutObject.from_dict(data.get("layout", {})) # 恢复 LayoutObject obj._coordinate = CoordinateObject.from_dict(data.get("coordinate", {})) # 恢复 CoordinateObject obj._runs = [RunObject.from_dict(run) for run in data.get("runs", [])] # 恢复 RunObject 列表 obj._data_id = data.get("data_id", None) obj._position = Position.from_dict(data.get("position", {})) return obj def __repr__(self): return f'{self.__class__.__name__}()[TEXT="{self._text}"]' @property def data_id(self): return self._data_id @data_id.setter def data_id(self, new_value): assert type(new_value) == int self._data_id = new_value @property def text(self): return self._text @text.setter def text(self, new_value): assert type(new_value) == str self._text = new_value @property def runs(self): return self._runs @runs.setter def runs(self, new_value): assert type(new_value) == list self._runs = new_value @property def coordinate(self): return self._coordinate @coordinate.setter def coordinate(self, new_value): assert isinstance(new_value, CoordinateObject) self._coordinate = new_value @property def layout(self): return self._layout @layout.setter def layout(self, new_value): assert isinstance(new_value, LayoutObject) self._layout = new_value @property def style(self): return self._style @style.setter def style(self, new_value): assert isinstance(new_value, StyleObject) self._style = new_value @property def position(self): return self._position @position.setter def position(self, new_value): assert isinstance(new_value, Position) self._position = new_value @staticmethod def lstrip_special_char(title): """ 去除title左边的特殊字符 """ built_delims = ["、", ",", ".", " "] for sep in built_delims: title = title.lstrip(sep) return title def get_data(self): """精简化输出支持""" data = { 'type': 'text', 'content': self.text, 'parent_content': self.layout.parent_content, "chapter": "", "title": "", "desc": "", "data_id": self.data_id, "index": -1 } if hasattr(self.layout, "is_chapter_title"): if self.layout.is_chapter_title: chapter = self.layout.chapter_id if chapter not in self.text.replace("\u3000", " ").replace(".", ".").replace('-', '.'): logging.info(f'start to translate text 0: {_("章节号和标题不匹配,请检查!")}') else: title = self.text.replace("\u3000", " ").replace(".", ".").replace('-', '.').split(chapter, maxsplit=1)[1].strip(getattr(self, "customized_sep", " ")) title = self.lstrip_special_char(title) data["chapter"] = chapter data["title"] = title logging.info(f'start to translate text 1: {_("这段文本是章节标题,章节号:")}') data["desc"] = _("这段文本是章节标题,章节号:") + chapter + "," + _("标题为:") + title else: logging.info(f'start to translate text 2: {_("这段文本是纯内容,不是章节标题,没有章节号。")}') data["desc"] = _("这段文本是纯内容,不是章节标题,没有章节号。") data["index"] = self.index if hasattr(self, "index") else -1 else: logging.info(f'start to translate text 3: {_("这段文本是纯内容,不是章节标题,没有章节号。")}') # 普通文本 data["desc"] = _("这段文本是纯内容,不是章节标题,没有章节号。") if self.coordinate.desc: data["coord"] = self.coordinate.desc else: data["page_num"] = self.layout.page_id return data def get_chars(self): """ 获取文本对象中的每个字及样式 去除整行文字的前后连续空格,保留中间的空格和样式 """ # 去除整行文字的前后连续空格,保留中间的空格和样式 full_text = ''.join(str(run.text) for run in self.runs).strip() data_list = [] current_index = 0 # 用于跟踪 full_text 的匹配位置 for run in self.runs: for char in str(run.text): # 跳过前后被去掉的空格 if current_index >= len(full_text): break # 如果字符匹配 full_text 中的字符,则添加到结果列表 if char == full_text[current_index]: data_list.append(CharObject(char, run.style)) current_index += 1 return data_list def get_html_text(self): """ 获取带有样式html文本字符串 """ html = "" for run in self.runs: # 字体样式 bg_color = run.style.background_color # 可为"" font_color = run.style.font_color # 可为"" font_family = run.style.font_family # 可为"" font_size = run.style.font_size.strip("pt") if font_size: font_size = int(float(font_size) * 1.3) # 加粗、倾斜 bold = run.style.font_style.bold italic = run.style.font_style.italic normal = run.style.font_style.normal # 装饰线 strike_out = run.style.font_style.strikeout underline = run.style.font_style.underline html += "<span style='" # 拼接样式 if not normal: if strike_out: html += "text-decoration: line-through;" elif underline: html += "text-decoration: underline;" else: html += "text-decoration: none;" if bold: html += "font-weight: bold;" if italic: html += "font-style: italic;" if font_color: html += "color: %s;" % font_color if font_family: html += "font-family: %s;" % font_family if font_size: html += "font-size: %dpx;" % font_size if bg_color: html += "background-color: %s;" % bg_color html += "'>" # 拼接文本 html += run.text + "</span>" return html def get_chapter_id(self): """ 获取文本对象章节号字符串, 返回章节id字符串 或者 空(无章节号) """ return getattr(self.layout, "chapter_id", "") class RunObject(BaseObject): """文本片段对象""" def __init__(self): self._text = '' # 完整内容 self._style = StyleObject() # 节段文本样式对象 self._layout = LayoutObject() # 文本片段布局对象 self._coordinate = CoordinateObject() # 文本的坐标 self._type = '' # 文本片段类型:text(普通文本);br(分页标识); @property def text(self): return self._text @text.setter def text(self, new_value): assert type(new_value) == str self._text = new_value @property def type(self): return self._type @type.setter def type(self, new_value): assert type(new_value) == str self._type = new_value @property def coordinate(self): return self._coordinate @coordinate.setter def coordinate(self, new_value): assert isinstance(new_value, CoordinateObject) self._coordinate = new_value @property def layout(self): return self._layout @layout.setter def layout(self, new_value): assert isinstance(new_value, LayoutObject) self._layout = new_value @property def style(self): return self._style @style.setter def style(self, new_value): assert isinstance(new_value, StyleObject) self._style = new_value def to_dict(self): return {"text": self._text, "style": self._style.to_dict()} """ @Author : 王定雄 @Date : 2024-10-29 @Desc : 图片对象的数据结构的定义 """ from kotei_omp.data.base_object import BaseObject from kotei_omp.data.layout import LayoutObject from kotei_omp.data.position import Position from kotei_omp.data.style import StyleObject from kotei_omp.data.coordinate import CoordinateObject class PictureObject(BaseObject): """图片对象""" def __init__(self): self._type = "picture" self._id = '' # 图片ID self._name = '' # 图片名称 self._width = '' # 宽 self._height = '' # 高 self._digest = '' # 图片数据的hash值 self._data = '' # 图片二进制数据的base64编码 self._layout = LayoutObject() # 文本布局对象 self._style = StyleObject() # 样式 self._coordinate = CoordinateObject() # 坐标 self._to_coordinate = CoordinateObject() self._data_id = None # 唯一标识 self._position = Position() def to_dict(self): """ 将 PictureObject 对象转换为字典 """ return { "type": self._type, "id": self._id, "name": self._name, "width": self._width, "height": self._height, "digest": self._digest, "data": self._data, "layout": self._layout.to_dict(), # 调用 LayoutObject 的 to_dict 方法 "style": self._style.to_dict(), # 调用 StyleObject 的 to_dict 方法 "coordinate": self._coordinate.to_dict(), # 调用 CoordinateObject 的 to_dict 方法 "data_id": self._data_id, "position": self._position.to_dict() } @classmethod def from_dict(cls, data): """ 从字典创建 PictureObject 实例 """ obj = cls() obj._type = data.get("type", "picture") obj._id = data.get("id", '') obj._name = data.get("name", '') obj._width = data.get("width", '') obj._height = data.get("height", '') obj._digest = data.get("digest", '') obj._data = data.get("data", '') obj._layout = LayoutObject.from_dict(data.get("layout", {})) # 恢复 LayoutObject obj._style = StyleObject.from_dict(data.get("style", {})) # 恢复 StyleObject obj._coordinate = CoordinateObject.from_dict(data.get("coordinate", {})) # 恢复 CoordinateObject obj._data_id = data.get("data_id", None) obj._position = Position.from_dict(data.get("position", {})) return obj def __repr__(self): return f'{self.__class__.__name__}()[{str(self)}]' def __str__(self): coordinate_str = f'\nCoordinate: {self._coordinate.desc}' if self._coordinate.desc else '' return f'Image [{self._name}]: Width:{self._width}, Height:{self._height}. \nType:{self._type}. \nOffset: Top:{self._coordinate.top or 0},Left:{self._coordinate.left or 0}.{coordinate_str}' @property def data_id(self): return self._data_id @data_id.setter def data_id(self, new_value): assert type(new_value) == int self._data_id = new_value @property def id(self): return self._id @id.setter def id(self, new_value): assert type(new_value) == str self._id = new_value @property def name(self): return self._name @name.setter def name(self, new_value): assert type(new_value) == str self._name = new_value @property def width(self): return self._width @width.setter def width(self, new_value): assert type(new_value) == str self._width = new_value @property def height(self): return self._height @height.setter def height(self, new_value): assert type(new_value) == str self._height = new_value @property def digest(self): return self._digest @digest.setter def digest(self, new_value): assert type(new_value) == str self._digest = new_value @property def data(self): return self._data @data.setter def data(self, new_value): assert type(new_value) == str self._data = new_value @property def layout(self): return self._layout @layout.setter def layout(self, new_value): assert isinstance(new_value, LayoutObject) self._layout = new_value @property def style(self): return self._style @style.setter def style(self, new_value): assert isinstance(new_value, StyleObject) self._style = new_value @property def coordinate(self): return self._coordinate @coordinate.setter def coordinate(self, new_value): assert isinstance(new_value, CoordinateObject) self._coordinate = new_value @property def to_coordinate(self): return self._to_coordinate @to_coordinate.setter def to_coordinate(self, new_value): assert isinstance(new_value, CoordinateObject) self.to_coordinate = new_value @property def position(self): return self._position @position.setter def position(self, new_value): assert isinstance(new_value, Position) self._position = new_value def get_data(self): """精简化输出支持""" data = { "data_id": self.data_id, 'type': 'picture', "parent_content": self.layout.parent_content, 'content': { 'id': self.id, 'name': self.name, 'width': self.width, 'height': self.height, 'data': self.data, 'digest': self.digest, }, "index": self.index if hasattr(self, "index") else 0 } if self.coordinate.desc: data["coord"] = self.coordinate.desc else: data["page_num"] = self.layout.page_id return data """ @Author : 王定雄 @Date : 2024-10-29 @Desc : 图形对象的数据结构的定义 """ from kotei_omp.data.base_object import BaseObject from kotei_omp.data.layout import LayoutObject from kotei_omp.data.position import Position from kotei_omp.data.style import StyleObject from kotei_omp.data.coordinate import CoordinateObject class GraphicObject(BaseObject): """图形对象""" def __init__(self): self._type = "graphic" self._id = '' # ID self._name = '' # 名称 self._width = '' # 宽 self._height = '' # 高 self._digest = '' # 图片数据的hash值 self._data = '' # 图片二进制数据的base64编码 self._text = '' # 图形文本框内容 self._graphic_type = '' # 类型,如矩形rect、线条line、嵌入对象等 self._layout = LayoutObject() # 文本布局对象 self._style = StyleObject() # 样式 self._coordinate = CoordinateObject() # 坐标位置 self._to_coordinate = CoordinateObject() self._data_id = None # 唯一标识 self._position = Position() def to_dict(self): """ 将 GraphicObject 对象转换为字典 """ return { "type": self._type, "id": self._id, "name": self._name, "width": self._width, "height": self._height, "digest": self._digest, "data": self._data, "text": self._text, "graphic_type": self._graphic_type, "layout": self._layout.to_dict(), # 调用 LayoutObject 的 to_dict 方法 "style": self._style.to_dict(), # 调用 StyleObject 的 to_dict 方法 "coordinate": self._coordinate.to_dict(), # 调用 CoordinateObject 的 to_dict 方法 "data_id": self._data_id, "position": self._position.to_dict() } @classmethod def from_dict(cls, data): """ 从字典创建 GraphicObject 实例 """ obj = cls() obj._type = data.get("type", "graphic") obj._id = data.get("id", '') obj._name = data.get("name", '') obj._width = data.get("width", '') obj._height = data.get("height", '') obj._digest = data.get("digest", '') obj._data = data.get("data", '') obj._text = data.get("text", '') obj._graphic_type = data.get("graphic_type", '') obj._layout = LayoutObject.from_dict(data.get("layout", {})) # 恢复 LayoutObject obj._style = StyleObject.from_dict(data.get("style", {})) # 恢复 StyleObject obj._coordinate = CoordinateObject.from_dict(data.get("coordinate", {})) # 恢复 CoordinateObject obj._data_id = data.get("data_id", None) obj._position = Position.from_dict(data.get("position", {})) return obj def __repr__(self): return f'{self.__class__.__name__}()[{str(self) }]' def __str__(self): coordinate_str = f'\nCoordinate: {self._coordinate.desc}' if self._coordinate.desc else '' return f'Image [{self._name}]: Width:{self._width}, Height:{self._height}. \nType:{self._type}. \nOffset: Top:{self._coordinate.top or 0},Left:{self._coordinate.left or 0}.{coordinate_str}' @property def position(self): return self._position @position.setter def position(self, new_value): assert isinstance(new_value, Position) self._position = new_value @property def data_id(self): return self._data_id @data_id.setter def data_id(self, new_value): assert type(new_value) == int self._data_id = new_value @property def id(self): return self._id @id.setter def id(self, new_value): assert type(new_value) == str self._id = new_value @property def name(self): return self._name @name.setter def name(self, new_value): assert type(new_value) == str self._name = new_value @property def width(self): return self._width @width.setter def width(self, new_value): assert type(new_value) == str self._width = new_value @property def height(self): return self._height @height.setter def height(self, new_value): assert type(new_value) == str self._height = new_value @property def digest(self): return self._digest @digest.setter def digest(self, new_value): assert type(new_value) == str self._digest = new_value @property def data(self): return self._data @data.setter def data(self, new_value): assert type(new_value) == str self._data = new_value @property def text(self): return self._text @text.setter def text(self, new_value): assert type(new_value) == str self._text = new_value @property def graphic_type(self): return self._graphic_type @graphic_type.setter def graphic_type(self, new_value): assert type(new_value) == str self._graphic_type = new_value @property def layout(self): return self._layout @layout.setter def layout(self, new_value): assert isinstance(new_value, LayoutObject) self._layout = new_value @property def style(self): return self._style @style.setter def style(self, new_value): assert isinstance(new_value, StyleObject) self._style = new_value @property def coordinate(self): return self._coordinate @coordinate.setter def coordinate(self, new_value): assert isinstance(new_value, CoordinateObject) self._coordinate = new_value @property def to_coordinate(self): return self._to_coordinate @to_coordinate.setter def to_coordinate(self, new_value): assert isinstance(new_value, CoordinateObject) self.to_coordinate = new_value def get_data(self): """精简化输出支持""" data = { "data_id": self.data_id, 'type': 'graphic', "parent_content": self.layout.parent_content, 'content': { 'id': self.id, 'name': self.name, 'width': self.width, 'height': self.height, 'data': self.data, 'digest': self.digest, 'text': self.text, }, "index": self.index if hasattr(self, "index") else 0 } if self.coordinate.desc: data["coord"] = self.coordinate.desc else: data["page_num"] = self.layout.page_id if hasattr(self, 'text_obj'): runs_style_obj = [] from kotei_omp.data.table import get_text_obj_runs_style get_text_obj_runs_style(self.text_obj, runs_style_obj) if runs_style_obj: data['runs_style'] = runs_style_obj return data 完善这三个类的类图 ┌──────────────────────────────┐ │ TextObject │ ├──────────────────────────────┤ │ - text: str │ ← 文本内容 │ - runs: List[RunObject] │ ← 文本片段列表 │ - style: StyleObject │ ← 文本样式 ├──────────────────────────────┤ │ + to_dict(): dict │ ← 转换为字典 │ + from_dict(data: dict): cls │ ← 从字典创建实例 └──────────────────────────────┘
10-29
""" @Author : 王定雄 @Date : 2024-10-29 @Desc : 表格对象的数据结构的定义 """ import logging from datetime import datetime from typing import List from kotei_omp.data.base_object import BaseObject from kotei_omp.data.border import CellBorderObject from kotei_omp.data.comment import CommentObject from kotei_omp.data.coordinate import CoordinateObject from kotei_omp.data.layout import LayoutObject from kotei_omp.data.position import Position, Context from kotei_omp.data.style import StyleObject from kotei_omp.data.text import TextObject from kotei_omp.data.picture import PictureObject from kotei_omp.data.graphic import GraphicObject from kotei_i18n.api import _ class TableBaseObject(BaseObject): def __init__(self): self._layout = LayoutObject() # 布局信息 self._style = StyleObject() # 样式 self._border = CellBorderObject() # 边框 self._coordinate = CoordinateObject() # 坐标 self._data_id = None # 唯一标识 def to_dict(self): """ 将 TableBaseObject 对象转换为字典 """ return { "layout": self._layout.to_dict(), "style": self._style.to_dict(), "border": self._border.to_dict(), "coordinate": self._coordinate.to_dict(), "data_id": self._data_id, } @classmethod def from_dict(cls, data): """ 从字典创建 TableBaseObject 实例 """ obj = cls() obj._layout = LayoutObject.from_dict(data.get("layout", {})) # 调用 LayoutObject 的 from_dict 方法 obj._style = StyleObject.from_dict(data.get("style", {})) # 调用 StyleObject 的 from_dict 方法 obj._border = CellBorderObject.from_dict(data.get("border", {})) # 调用 CellBorderObject 的 from_dict 方法 obj._coordinate = CoordinateObject.from_dict(data.get("coordinate", {})) # 调用 CoordinateObject 的 from_dict 方法 obj._data_id = data.get("data_id", '') return obj @property def data_id(self): return self._data_id @data_id.setter def data_id(self, new_value): if not new_value: new_value = 0 assert type(new_value) == int self._data_id = new_value @property def layout(self): return self._layout @layout.setter def layout(self, new_value): assert isinstance(new_value, LayoutObject) self._layout = new_value @property def style(self): return self._style @style.setter def style(self, new_value): assert isinstance(new_value, StyleObject) self._style = new_value @property def border(self): return self._border @border.setter def border(self, new_value): assert isinstance(new_value, CellBorderObject) self._border = new_value @property def coordinate(self): return self._coordinate @coordinate.setter def coordinate(self, new_value): assert isinstance(new_value, CoordinateObject) self._coordinate = new_value def format_row(self, row_obj, sep_col=''): """格式化表格数据 :param row_obj: 一维列表 :param sep_col: 列分隔符 :return: [str] 返回格式化的字符串 """ row = [] for cell in row_obj.cells: if cell: row.append(str(cell.text)) return sep_col.join(row) def check_specific_style(run): style_obj = run.style if style_obj.font_family or style_obj.font_size or style_obj.font_color not in ["", "#000000"] or style_obj.background_style or style_obj.background_color: specific_style = True elif not style_obj.font_style.normal: specific_style = True else: specific_style = False return specific_style def get_text_obj_runs_style(text_obj, runs_style_obj): last_style = None for run in text_obj.runs: if check_specific_style(run): run_style_dict = run.to_dict() if isinstance(run_style_dict["text"], datetime): # run_style_dict["text"] = run_style_dict["text"].isoformat() # 将 datetime 转换为 ISO 格式字符串 run_style_dict["text"] = run_style_dict["text"].strftime('%Y/%m/%d') this_style = run_style_dict["style"] if this_style == last_style: last_run_style_dict = runs_style_obj[-1] last_run_style_dict["text"] += run_style_dict["text"] else: runs_style_obj.append(run_style_dict) last_style = this_style else: last_style = {} class TableObject(TableBaseObject): """ 表格对象 """ def __init__(self): super().__init__() self._type = "table" self._rows: list[RowObject] = [] # 表格行对象 self._head_type = 'horizontal' # 表格表头类型 horizontal:水平 ; vertical: 垂直 self._head_list = [] # 表格表头所在下标 horizontal时 保存行下标; vertical时保存的列下标 self._last_coordinate = '' # 未知作用 def to_dict(self): """ 将 TableObject 对象转换为字典 """ res = { "type": self._type, "rows": [row.to_dict() for row in self._rows], # 转换每个行对象为字典 "head_type": self._head_type, "head_list": self._head_list, **super().to_dict() # 合并父类的部分属性 } if self._last_coordinate: res["last_coordinate"] = self._last_coordinate # print(res["last_coordinate"]) return res @classmethod def from_dict(cls, data): """ 从字典创建 TableObject 实例 """ obj = cls() base_obj = super(TableObject, cls).from_dict(data) # Copy attributes initialized by the superclass obj._layout = base_obj._layout obj._style = base_obj._style obj._border = base_obj._border obj._coordinate = base_obj._coordinate obj._data_id = base_obj._data_id obj._type = data.get("type", "table") obj._rows = [RowObject.from_dict(row_data) for row_data in data.get("rows", [])] # 恢复行对象列表 obj._head_type = data.get("head_type", 'horizontal') obj._head_list = data.get("head_list", []) if data.get("last_coordinate", ''): obj._last_coordinate = data.get("last_coordinate", '') return obj def __repr__(self): return f'{self.__class__.__name__}()[{str(self)}]' def __str__(self): table_content = '' for row in self._rows: table_content += self.format_row(row, '\t') break return table_content @property def rows(self): return self._rows @rows.setter def rows(self, new_value): assert type(new_value) == list self._rows = new_value @property def head_type(self): return self._head_type @head_type.setter def head_type(self, new_value): assert new_value in ['horizontal', 'vertical'] self._head_type = new_value @property def head_list(self): return self._head_list @head_list.setter def head_list(self, new_value): assert type(new_value) == list self._head_list = new_value def get_data(self): """精简化输出支持""" table_data = [] merged_cells = [] annotations = [] runs_styles = [] images = [] for rid, row in enumerate(self.rows): row_data = [] for cid, cell in enumerate(row.cells): shapes = [] runs_style_obj = [] for item in cell.content: if isinstance(item, (PictureObject, GraphicObject)): shapes.append(item) elif isinstance(item, TextObject): get_text_obj_runs_style(item, runs_style_obj) # if shapes: # content = {'text': cell.text, 'picture': [], 'graphic': []} # for shape in shapes: # if isinstance(shape, PictureObject): # content['picture'].append(shape.get_data()) # elif isinstance(shape, GraphicObject): # content['graphic'].append(shape.get_data()) # else: content = cell.text row_data.append(content) if cell.comment.text: annotation = {"content": cell.comment.text, "row": rid, 'column': cid} annotations.append(annotation) if shapes: image_dict = {"cell_content": [shape.get_data() for shape in shapes], "row": rid, 'column': cid} images.append(image_dict) if runs_style_obj: runs_style = {"run_style": runs_style_obj, "row": rid, 'column': cid} runs_styles.append(runs_style) # 获取有合并的单元格信息 if cell.merged_ranges: mr = cell.merged_ranges if hasattr(cell, "relative_merged_ranges") and cell.relative_merged_ranges: mr = cell.relative_merged_ranges merged_cells.append({ "type": "cell", "row_index": rid, "col_index": cid, "merged_range": mr }) table_data.append(row_data) row_cnt = len(self.rows) col_cnt = len(self.rows[0].cells) sub_string = "" for i in self.head_list: sub_string += _("表头是第%d行、") % (i + 1) logging.info(f'start to translate table desc 4: {_("表格有%d行,%d列,%s") % (row_cnt, col_cnt, sub_string[:-1])}') data = { 'type': 'table', 'content': table_data, 'annotations': annotations, 'runs_style': runs_styles, 'images': images, 'parent_content': self.layout.parent_content, "row_cnt": row_cnt, "col_cnt": col_cnt, "head": self.head_list, 'head_type': self.head_type, "desc": _("表格有%d行,%d列,%s") % (row_cnt, col_cnt, sub_string[:-1]), "data_id": self.data_id, "merged_cells": merged_cells, "index": self.index if hasattr(self, "index") else -1 } if self.coordinate.desc: data["coord"] = self.coordinate.desc else: data["page_num"] = self.layout.page_id return data def get_heads(self): """ 获取cell对象对应的head列表 :return: """ if not self.head_list or not self.rows: return [] heads = [] if self.head_type == "horizontal": for index in self.head_list: heads.append(self.rows[index].cells) else: for index in self.head_list: head = [] for row in self.rows: head.append(row.cells[index]) heads.append(head) return heads @staticmethod def _get_title(curr_ref): if type(curr_ref) == TextObject: return curr_ref.text elif hasattr(curr_ref, "layout") and curr_ref.layout.prev_ref: return TableObject._get_title(curr_ref.layout.prev_ref) else: return "" def get_title(self): return TableObject._get_title(self.layout.prev_ref) def get_chapter_id(self): """ 获取表格对象章节号字符串, 返回章节id字符串 或者 空(无章节号) """ return getattr(self.layout, "chapter_id", "") def is_same_pos(self, table_obj) -> bool: """ 判定两个表格对象的位置坐标是否相同 """ return self.coordinate.desc == table_obj.coordinate.desc def get_merged_ranges(self, include_cell_obj=False): """ 获取表格内所有存在单元格合并的范围 :param include_cell_obj: bool类型,False时仅以列表形式返回合并范围元组 True时返回字典,key为合并范围元组,value为该合并范围内的CellObject对象 :param return: list or dict """ temp_dict = {} row_num = len(self.rows) if row_num == 0: # 空表格 return {} if include_cell_obj else [] col_num = len(self.rows[0].cells) for r in range(row_num): for c in range(col_num): cell_obj = self.rows[r].cells[c] cell_merge_range = cell_obj.merged_ranges # 单元格不存在合并,则跳过 if not cell_merge_range: continue # 存在时,则存入哈希中 cur_merge_range = tuple(cell_merge_range) if cur_merge_range not in temp_dict: temp_dict[cur_merge_range] = [cell_obj] else: temp_dict[cur_merge_range].append(cell_obj) if not include_cell_obj: return list(temp_dict.keys()) return temp_dict # def get_col_list(self, col_name=None, col_index=None): # """ # 根据表头内容或者列索引,获取对应列的对象列表 # :param col_name: str类型,列的表头内容 # :param col_index: int类型,列的索引 # return: list # """ # result = [] # if col_name: # head_list = self.get_heads() # head_content_list = [] # for head in head_list: # head_content = [] # for item in head: # head_content.append(str(item.text).strip()) # head_content_list.append(head_content) # for head_content in head_content_list: # if col_name.strip() in head_content: # col_index = head_content.index(col_name.strip()) # break # if col_index is not None: # for r in self.rows: # result.append(r.cells[col_index]) # return result def get_col_list(self, col_name=None, col_index=None): """ 根据表头内容或者列索引,获取对应列的对象列表 :param col_name: str类型,列的表头内容 :param col_index: int类型,列的索引 return: list """ result = [] if col_name: head_list = self.get_heads() head_content_dict = dict() for head in head_list: for index, item in enumerate(head): if index not in head_content_dict: head_content_dict[index] = str(item.text).strip() else: head_content_dict[index] += str(item.text).strip() head_content_list = list(head_content_dict.values()) for item_index, head_content in enumerate(head_content_list): if col_name.strip() in head_content: col_index = item_index break if col_index is not None: if self.head_type == 'horizontal': for r in self.rows: result.append(r.cells[col_index]) else: result.extend(self.rows[col_index].cells) return result class RowObject(TableBaseObject): """ 表格行对象 """ def __init__(self): super().__init__() self._type = "table_row" self._row_index = '' # 行序号 self._cells: List[CellObject] = [] # 表格列对象 def __repr__(self): return f'{self.__class__.__name__}()[{str(self)}]' def __str__(self): return self.format_row(self, '\t') @property def row_index(self): return self._row_index @row_index.setter def row_index(self, new_value): assert type(new_value) == int self._row_index = new_value @property def cells(self): return self._cells @cells.setter def cells(self, new_value): assert type(new_value) == list self._cells = new_value if new_value: self.coordinate.desc = new_value[0].coordinate.desc class CellObject(TableBaseObject): """ 表格的单元格对象 """ def __init__(self): super().__init__() self._type = "table_cell" self._text = "" # 内容 self._row_index = '' # 行序号 self._col_index = '' # 列序号 self._comment = CommentObject() # 批注 self._content = [] # 单元格的内容对象列表 self._merged_ranges = [] # 合并单元格的范围 [0,0,1,3] self._style = StyleObject() # 样式 self._position = Position() self._is_merged = False self._is_merged_start = True def to_dict(self): """ 将 CellObject 对象转换为字典 """ return { "type": self._type, "text": self._text, "row_index": self._row_index, "col_index": self._col_index, "comment": self._comment.to_dict(), # 调用 CommentObject 的 to_dict 方法 "content": [item.to_dict() for item in self._content], # 递归转换内容对象列表 "merged_ranges": self._merged_ranges, "style": self._style.to_dict(), # 调用 StyleObject 的 to_dict 方法 "position": self._position.to_dict(), **super().to_dict() # 合并父类的部分属性 } @classmethod def from_dict(cls, data): """ 从字典创建 CellObject 实例 """ obj = cls() base_obj = super(CellObject, cls).from_dict(data) # Copy attributes initialized by the superclass obj._layout = base_obj._layout obj._style = base_obj._style obj._border = base_obj._border obj._coordinate = base_obj._coordinate obj._data_id = base_obj._data_id obj._type = data.get("type", "table_cell") obj._text = data.get("text", "") obj._row_index = data.get("row_index", '') obj._col_index = data.get("col_index", '') obj._comment = CommentObject.from_dict(data.get("comment", {})) # 调用 CommentObject 的 from_dict 方法 obj._content = [TextObject.from_dict(e) if e.get("type") == "text" else PictureObject.from_dict(e) if e.get("type") == "picture" else GraphicObject.from_dict(e) if e.get("type") == "graphic" else e for e in data.get("content", [])]# 递归恢复内容对象列表 obj._merged_ranges = data.get("merged_ranges", []) obj._style = StyleObject.from_dict(data.get("style", {})) # 调用 StyleObject 的 from_dict 方法 obj._position = Position.from_dict(data.get("position", {})) return obj @property def text(self): return self._text @text.setter def text(self, new_value): assert type(new_value) == str self._text = new_value @property def row_index(self): return self._row_index @row_index.setter def row_index(self, new_value): assert type(new_value) == int self._row_index = new_value @property def col_index(self): return self._col_index @col_index.setter def col_index(self, new_value): assert type(new_value) == int self._col_index = new_value @property def comment(self): return self._comment @comment.setter def comment(self, new_value): assert isinstance(new_value, CommentObject) self._comment = new_value @property def content(self): return self._content @content.setter def content(self, new_value): assert type(new_value) == list self._content = new_value @property def merged_ranges(self): return self._merged_ranges @merged_ranges.setter def merged_ranges(self, new_value): self._merged_ranges = new_value @property def style(self): return self._style @style.setter def style(self, new_value): assert isinstance(new_value, StyleObject) self._style = new_value def get_heads(self): """ 获取cell对象对应的head列表 :param cell:CellObject对象 :return: """ # 获取当前单元格所在的表格对象 row_obj = self.layout.parent_ref if not isinstance(row_obj, RowObject): return [] table_ = row_obj.layout.parent_ref if table_ is None: return [] if not table_.head_list or not table_.rows: return [] heads = [] if table_.head_type == "horizontal": for index in table_.head_list: heads.append(table_.rows[index].cells[self.col_index]) else: for index in table_.head_list: heads.append(table_.rows[self.row_index].cells[index]) return heads def get_context(self) -> Context: """ 获取cell对象对应的上下文信息(cell所在行,cell所在table的表头和第一行内容的第一列) :param cell:CellObject对象 :return: """ res = Context() # 获取当前单元格所在的表格对象 row_obj = self.layout.parent_ref if row_obj is None: return res table_ = row_obj.layout.parent_ref if table_ is None: return res row_index = int(self.row_index) col_index = int(self.col_index) # 大模型解析失败,默认第一行是表头 if table_.head_type == "": table_.head_type == "horizontal" table_.head_list = [0] if table_.head_type == "horizontal": res.current_row = "|".join(cell.text for cell in row_obj.cells) # 如果没有表头,则将表头设置为第一行的逻辑不再使用, # 如果后续有问题,也不要将第一行设置为表头,在写SCL时会造成混乱,需要考虑其他解决方案 # if len(table_.head_list) == 0: # table_.head_list = [0] # header_index = table_.head_list[0] # header_row = table_.rows[header_index] # res.header_list = "|".join(cell.text for cell in header_row.cells) # res.cell_header = header_row.cells[col_index].text if len(table_.head_list) != 0: header_index = table_.head_list[0] header_row = table_.rows[header_index] res.header_list = "|".join(cell.text for cell in header_row.cells) res.cell_header = header_row.cells[col_index].text # 前后行的数据 if row_index + 1 < len(table_.rows): next_row = table_.rows[row_index + 1] res.next_context = "|".join(cell.text for cell in next_row.cells) if row_index - 1 > 0: prev_row = table_.rows[row_index - 1] res.pre_context = "|".join(cell.text for cell in prev_row.cells) # 列表头逻辑 (vertical) elif table_.head_type == "vertical": # 当前列的数据 current_col = [row.cells[col_index].text for row in table_.rows] res.current_row = "|".join(current_col) # 表头数据(取第一个表头列的行) # if len(table_.head_list) == 0: # table_.head_list = [0] # header_col_index = table_.head_list[0] # res.header_list = "|".join(row.cells[header_col_index].text for row in table_.rows) # res.cell_header = table_.rows[row_index].cells[header_col_index].text if len(table_.head_list) != 0: table_.head_list = [0] header_col_index = table_.head_list[0] res.header_list = "|".join(row.cells[header_col_index].text for row in table_.rows) res.cell_header = table_.rows[row_index].cells[header_col_index].text # 前后列的数据 if col_index + 1 < len(table_.rows[0].cells): next_col = [row.cells[col_index + 1].text for row in table_.rows] res.next_context = "|".join(next_col) if col_index - 1 > 0: prev_col = [row.cells[col_index - 1].text for row in table_.rows] res.pre_context = "|".join(prev_col) return res 给出这五个类的类图
最新发布
10-29
<CheckBox IsChecked="{Binding IsAutoPassEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Command="{Binding EnableOrDisableAutoPassCommand}"/> <TextBlock Style="{StaticResource CollaborationBulletinTailLabelStyle}" Text="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.EnableAutoPublish, FallbackValue='Enable Auto Pass'}"/> 我在做一个wpf项目,我想将这个check box添加一个底色当我打钩后是绿色 当我未打钩是红色 就像下面这个button代码 <Button Height="22" Command="{Binding EnableOrDisableAutoPassCommand}"> <Button.Style> <Style TargetType="{x:Type Button}" BasedOn="{StaticResource CollaborationBulletinButtonStyle}"> <Setter Property="Content" Value="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.EnableAutoPublish, FallbackValue='Enable Auto Pass'}" /> <Style.Triggers> <DataTrigger IsChecked="{Binding IsAutoPassEnabled, UpdateSourceTrigger=PropertyChanged}" Value="False"> <Setter Property="Content" Value="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.EnableAutoPublish, FallbackValue='Enable Auto Pass'}" /> <Setter Property="Background" Value="Green" /> </DataTrigger> <DataTrigger IsChecked="{Binding IsCoverageEnabled, UpdateSourceTrigger=PropertyChanged}" Value="True"> <Setter Property="Content" Value="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.CloseAutoPublish, FallbackValue='Close Auto Pass'}" /> <Setter Property="Background" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button>
08-05
public bool? IsChecked { get { object value = GetValue(IsCheckedProperty); if (value == null) { return null; } return (bool)value; } set { SetValue(IsCheckedProperty, value.HasValue ? BooleanBoxes.Box(value.Value) : null); } } <CheckBox IsChecked="{Binding IsAutoPassEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Command="{Binding EnableOrDisableAutoPassCommand}"/> <TextBlock Style="{StaticResource CollaborationBulletinTailLabelStyle}" Text="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.EnableAutoPublish, FallbackValue='Enable Auto Pass'}"/> 在这个wpf中 我想将他ischeck这个逻辑改到从check box改成 button <Button Height="22" Command="{Binding EnableOrDisableAutoPassCommand}"> <Button.Style> <Style TargetType="{x:Type Button}" BasedOn="{StaticResource CollaborationBulletinButtonStyle}"> <Setter Property="Content" Value="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.EnableAutoPublish, FallbackValue='Enable Auto Pass'}" /> <Style.Triggers> <DataTrigger Binding="{Binding IsAutoPassEnabled, UpdateSourceTrigger=PropertyChanged}" Value="False"> <Setter Property="Content" Value="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.EnableAutoPublish, FallbackValue='Enable Auto Pass'}" /> <Setter Property="Background" Value="Green" /> </DataTrigger> <DataTrigger Binding="{Binding IsCoverageEnabled, UpdateSourceTrigger=PropertyChanged}" Value="True"> <Setter Property="Content" Value="{globalizer:GlobalizedResource CollaborationBulletinView.Labels.CloseAutoPublish, FallbackValue='Close Auto Pass'}" /> <Setter Property="Background" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button>
08-05
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值