def captureFont(res, _from): result = {} if _from.bold != None: result["bold"] = _from.bold if _from.italic != None: try: result["italic"] = _from.italic except: result["italic"] = None if _from.color != None: result["color"] = captureColor(_from.color) if _from.fill != None: result["fill"] = captureFill(_from.fill) if _from.name != None: try: result["name"] = _from.name except: result["name"] = None if _from.size != None: try: result["size"] = Length(_from.size).pt except: result["size"] = None if _from.underline != None: try: result["underline"] == _from.underline except: result["underline"] = None return result
def add_pgb_page(slide, cur, total, left=0, top=0, height=100000, width_full=12192000, fore='89ABBF', past='A0CCEF'): left = Length(left) top = Length(top) text_height = Length(height * 0.95) height = Length(height) width_per = Length(width_full * ((cur) / (total))) width_full = Length(width_full) add_rect(slide, left, top, width_full, height, fore) add_rect(slide, left, top, width_per, height, past) add_text(slide, left, top, width_full, height, text_height, '%d/%d' % (cur, total))
def applyMargin(res, _from): res["margin_left"] = Length(_from.margin_left).pt res["margin_right"] = Length(_from.margin_right).pt res["margin_top"] = Length(_from.margin_top).pt res["margin_bottom"] = Length(_from.margin_bottom).pt
def applyMargin(res, _from): res["margin_left"] = Length(_from.margin_left).pt res["margin_right"] = Length(_from.margin_right).pt res["margin_top"] = Length(_from.margin_top).pt res["margin_bottom"] = Length(_from.margin_bottom).pt def captureSlideLayout(res, _from): res["placeholders"] = _from.placeholders output_slides = [] presentationObj = {} presentationObj["slides"] = output_slides presentationObj["slide_height"] = Length(prs.slide_height).pt presentationObj["slide_width"] = Length(prs.slide_width).pt print("//////////////////////////////////////////////////////////// slide") for slide in prs.slides: print("------------------- slide") output_slide = [] _parentSlide = {"slide": output_slide} output_slides.append(_parentSlide) if hasattr(slide, "slide_layout"): print(slide.slide_layout) _parentSlide["slide_layout"] = captureSlideLayout({}, slide.slide_layout) for shape in slide.shapes: print("%%%%%%%%%%%%%%%%%% - shape") print(shape)
def get_wrong_paper_ppt(self): """ 获取错题ppt """ current_app.logger.info(">>>>>>>>>>>>>>>>>>start_time:" + str(datetime.now())) args = parameter_required(("paperName", "classId", "errRate")) # 获取试卷 paper = j_paper.query.filter( j_paper.name == args.get("paperName")).first_("未找到该试卷") paper_id = paper.id # 获取题目列表 question_list = j_question.query.filter( j_question.paper_id == paper_id).all() if not question_list: return NoQuestion() # 题号list question_num_list = [] # 分数list question_score_list = [] for question in question_list: question_num_list.append(question.question_number) question_score_list.append(question.score) current_app.logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>question_num_list:" + str(question_num_list)) current_app.logger.info( ">>>>>>>>>>>>>>>>>>>>>>>>>question_score_list:" + str(question_score_list)) # 学生list student_id_list = [] student_list = j_student.query.filter( j_student.org_id == args.get("classId")).all() for student in student_list: student_id_list.append(student.id) if not student_id_list: return ClassNoStudent() current_app.logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>student_id_list:" + str(student_id_list)) answer_id_list = [] for student_id in student_id_list: filter_args = [ j_answer_booklet.paper_id == paper_id, j_answer_booklet.student_id == student_id ] if args.get("startTime"): filter_args.append( j_answer_booklet.create_time >= args.get("startTime")) if args.get("endTime"): filter_args.append( j_answer_booklet.create_time <= args.get("endTime")) answer_booklet_list = j_answer_booklet.query.filter( *filter_args).all() for answer_booklet_item in answer_booklet_list: answer_id_list.append(answer_booklet_item.id) current_app.logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>answer_id_list:" + str(answer_id_list)) # 总答卷数目 total_answer_booklet = len(answer_id_list) if total_answer_booklet == 0: return NoAnswer() # 要生成ppt的question列表 ppt_question_number_list = [] i = 0 while i < len(question_num_list): j = 0 for answer_id in answer_id_list: score = j_score.query.filter(j_score.booklet_id == answer_id, j_score.question_number == int(question_num_list[i]), j_score.score == question_score_list[i])\ .first() if score: j = j + 1 if (total_answer_booklet - j) / total_answer_booklet > float( args.get("errRate")) / 100: ppt_question_number_list.append(int(question_num_list[i])) i = i + 1 ppt_question_number_list.sort() if not ppt_question_number_list: return NoErrCode() # ppt用到的题目答案列表 question_answer_list = [] for question_number in ppt_question_number_list: question_answer_dict = {} ppt_question_answer = j_question.query.filter( j_question.question_number == str(question_number), j_question.paper_id == paper_id).first_("未找到题目") import re q_use_html = ppt_question_answer.contenthtml q_img_list = re.findall(r"<img.*?/>", ppt_question_answer.contenthtml) i = 0 q_img_src_list = [] for img in q_img_list: q_use_html = ppt_question_answer.contenthtml.replace( img, "{0" + "[0]".format(i) + "}") img_url = re.findall(r'.+?src="(\S+)"', img)[0] q_img_src_list.append("<img src='{0}'></img>".format(img_url)) i += 1 q_text = re.sub(r"</?(.+?)>", "", q_use_html) question_answer_dict["question"] = q_text.format(q_img_src_list) a_use_html = ppt_question_answer.answerhtml a_img_list = re.findall(r"<img.*?/>", ppt_question_answer.answerhtml) i = 0 a_img_src_list = [] for img in a_img_list: a_use_html = ppt_question_answer.answerhtml.replace( img, "{0" + "[0]".format(i) + "}") img_url = re.findall(r'.+?src="(\S+)"', img)[0] a_img_src_list.append("<img src='{0}'></img>".format(img_url)) i += 1 a_text = re.sub(r"</?(.+?)>", "", a_use_html) question_answer_dict["answer"] = a_text.format(a_img_src_list) question_answer_dict["knowledge"] = ppt_question_answer.knowledge question_answer_list.append(question_answer_dict) current_app.logger.info(">>>>>>>>>>>>>>>>>>>question_answer_list:" + str(question_answer_list)) # 阿里云oss参数 auth = oss2.Auth(ACCESS_KEY_ID, ACCESS_KEY_SECRET) bucket = oss2.Bucket(auth, ALIOSS_ENDPOINT, ALIOSS_BUCKET_NAME) # 创建ppt prs = Presentation() # ppt样式-空白 blank_slide_layout = prs.slide_layouts[6] ppt_uuid = str(uuid.uuid1()) # 设置临时存储路径 if platform.system() == "Windows": pic_path = "D:\\jinrui_pic\\" + ppt_uuid + "\\" else: pic_path = "/tmp/jinrui_pic/" + ppt_uuid + "/" if not os.path.exists(pic_path): os.makedirs(pic_path) # 遍历题目-答案-考点 for question_answer in question_answer_list: # 创建幻灯片 slide = prs.slides.add_slide(blank_slide_layout) # 设置幻灯片背景 img_path = os.path.abspath("jinrui/control/ppt.jpg") back_pic = slide.shapes.add_picture(img_path, Inches(0), Inches(0), width=prs.slide_width, height=prs.slide_height) slide.shapes._spTree.remove(back_pic._element) slide.shapes._spTree.insert(2, back_pic._element) # 设置顶点尺寸 left = top = Inches(0.5) question_dict = question_answer["question"] print(question_dict) for question_item in [question_dict]: if question_item: question_item = question_item.replace( "<img src=\"", "#####").replace("></img>", "#####").replace( "<img src='", "#####") question_item_dict = question_item.split("#####") width = Inches(1) height = Inches(0.4) for row in question_item_dict: if row: if "https://" in row: if "\"" in row: row = row.split("\"")[0] row_dict_path = row.replace( "{0}{1}.{2}/".format( "https://", ALIOSS_BUCKET_NAME, ALIOSS_ENDPOINT), "").replace("\'", "") row_dict = row_dict_path.split("/") pic_save_path = pic_path + row_dict[-1] # 存储图片到本地 bucket.get_object_to_file( row_dict_path, pic_save_path) img = cv2.imread(pic_save_path) pic_width = img.shape[0] pic_height = img.shape[1] # 添加图片到ppt中 pic = slide.shapes.add_picture(pic_save_path, left, top, height=height) left = left + pic_width * height / pic_height # 移除图片 os.remove(pic_save_path) else: width = Inches(len(row) / 4) if left + width > Inches(12): use_width = Inches(12) - left from pptx.util import Length use_word = Length(4 * use_width).inches txBox = slide.shapes.add_textbox( left, top, use_width, height) tf = txBox.text_frame tf.text = row[0:int(use_word)] left = Inches(0.5) top = top + Inches(0.5) other_word_num = len(row) - use_word if other_word_num % 36 == 0: perform = other_word_num / 36 else: perform = int(other_word_num / 36) + 1 i = 0 while i < perform: txBox = slide.shapes.add_textbox( left, top, Inches( len(row[int(use_word) + 1 + 36 * i:int(use_word) + 36 * (i + 1) + 1]) / 4), height) tf = txBox.text_frame tf.text = row[int(use_word) + 1 + 36 * i:int(use_word) + 36 * (i + 1) + 1] left = Inches(0.5) top = top + Inches(0.5) i += 1 else: txBox = slide.shapes.add_textbox( left, top, width, height) tf = txBox.text_frame tf.text = row left = left + width left = Inches(0.5) top = top + Inches(0.5) # 创建幻灯片 slide = prs.slides.add_slide(blank_slide_layout) # 创建背景 img_path = os.path.abspath("jinrui/control/ppt.jpg") back_pic = slide.shapes.add_picture(img_path, Inches(0), Inches(0), width=prs.slide_width, height=prs.slide_height) slide.shapes._spTree.remove(back_pic._element) slide.shapes._spTree.insert(2, back_pic._element) # 设置顶点尺寸 left = top = Inches(0.5) # 考点与答案同页面 knowledge = "考点:【" + question_answer["knowledge"] + "】" txBox = slide.shapes.add_textbox(left, top, Inches(1), Inches(0.4)) tf = txBox.text_frame tf.text = knowledge answer_dict = question_answer["answer"] # 考虑考点高度值,增加答案起始高度 top = Inches(1) for answer_item in [answer_dict]: if answer_item: answer_item = answer_item.replace("<img src='", "#####").replace( "></img>", "#####") question_item_dict = answer_item.split("#####") width = Inches(1) height = Inches(0.4) for row in question_item_dict: if row: if "https://" in row: if "\"" in row: row = row.split("\"")[0] row_dict_path = row.replace( "{0}{1}.{2}/".format( "https://", ALIOSS_BUCKET_NAME, ALIOSS_ENDPOINT), "").replace("\'", "") row_dict = row_dict_path.split("/") pic_save_path = pic_path + row_dict[-1] # 存储图片到本地 bucket.get_object_to_file( row_dict_path, pic_save_path) img = cv2.imread(pic_save_path) pic_width = img.shape[0] pic_height = img.shape[1] # 添加图片到ppt中 pic = slide.shapes.add_picture(pic_save_path, left, top, height=height) left = left + pic_width * height / pic_height # 移除图片 os.remove(pic_save_path) else: width = Inches(len(row) / 4) if left + width > Inches(12): use_width = Inches(12) - left from pptx.util import Length use_word = Length(4 * use_width).inches txBox = slide.shapes.add_textbox( left, top, use_width, height) tf = txBox.text_frame tf.text = row[0:int(use_word)] left = Inches(0.5) top = top + Inches(0.5) other_word_num = len(row) - use_word if other_word_num % 36 == 0: perform = other_word_num / 36 else: perform = int(other_word_num / 36) + 1 i = 0 while i < perform: txBox = slide.shapes.add_textbox( left, top, Inches( len(row[int(use_word) + 1 + 36 * i:int(use_word) + 36 * (i + 1) + 1]) / 4), height) tf = txBox.text_frame tf.text = row[int(use_word) + 1 + 36 * i:int(use_word) + 36 * (i + 1) + 1] left = Inches(0.5) top = top + Inches(0.5) i += 1 else: txBox = slide.shapes.add_textbox( left, top, width, height) tf = txBox.text_frame tf.text = row left = left + width left = Inches(0.5) top = top + Inches(0.5) prs.save(pic_path + "ppt-" + ppt_uuid + ".pptx") ppt_url = "https://" + ALIOSS_BUCKET_NAME + "." + ALIOSS_ENDPOINT + "/" + "ppt-" + ppt_uuid + ".pptx" result = bucket.put_object_from_file( "ppt-" + ppt_uuid + ".pptx", pic_path + "ppt-" + ppt_uuid + ".pptx") current_app.logger.info(">>>>>>>>>>>>>>>>>>>oss_status:" + str(result.status)) current_app.logger.info(">>>>>>>>>>>>>>>>>>>ppt_url:" + ppt_url) shutil.rmtree(pic_path) current_app.logger.info(">>>>>>>>>>>>>>>>>>>end_time:" + str(datetime.now())) return { "code": 200, "success": True, "message": "获取成功", "data": { "url": ppt_url } }
def process_shape(self, shape, svg_parent, transform): #===================================================== id = id_from_name(shape.name) geometry = Geometry(shape) if id is not None and len(geometry) > 1: # Add a group to hold multiple paths ## We should really add a `.group` placeholder group = self.__dwg.g(id=id) svg_parent.add(group) svg_parent = group id = None for path in geometry.path_list: svg_path = self.__dwg.path(fill='none', class_='non-scaling-stroke') if id is not None: svg_path.attribs['id'] = id bbox = (shape.width, shape.height) if path.w is None else (path.w, path.h) T = transform @ DrawMLTransform(shape, bbox).matrix() current_point = None closed = False for c in path.getchildren(): if c.tag == DML('arcTo'): wR = geometry.attrib_value(c, 'wR') hR = geometry.attrib_value(c, 'hR') stAng = radians(geometry.attrib_value(c, 'stAng')) swAng = radians(geometry.attrib_value(c, 'swAng')) p1 = ellipse_point(wR, hR, stAng) p2 = ellipse_point(wR, hR, stAng + swAng) pt = (current_point[0] - p1[0] + p2[0], current_point[1] - p1[1] + p2[1]) phi = T.rotate_angle(0) large_arc_flag = 0 svg_path.push('A', *T.scale_length((wR, hR)), 180 * phi / PI, large_arc_flag, 1, *T.transform_point(pt)) current_point = pt elif c.tag == DML('close'): svg_path.push('Z') closed = True elif c.tag == DML('cubicBezTo'): coords = [] for p in c.getchildren(): pt = geometry.point(p) coords.extend(T.transform_point(pt)) current_point = pt svg_path.push('C', *coords) elif c.tag == DML('lnTo'): pt = geometry.point(c.pt) coords = T.transform_point(pt) svg_path.push('L', *coords) current_point = pt elif c.tag == DML('moveTo'): pt = geometry.point(c.pt) coords = T.transform_point(pt) svg_path.push('M', *coords) current_point = pt elif c.tag == DML('quadBezTo'): coords = [] for p in c.getchildren(): pt = geometry.point(p) coords.extend(T.transform_point(pt)) current_point = pt svg_path.push('Q', *coords) else: print('Unknown path element: {}'.format(c.tag)) if not isinstance(shape, pptx.shapes.connector.Connector): if shape.fill.type == MSO_FILL_TYPE.SOLID: svg_path.attribs['fill'] = self.__colour_map.lookup( shape.fill.fore_color) alpha = shape.fill.fore_color.alpha if alpha < 1.0: svg_path.attribs['opacity'] = alpha elif shape.fill.type == MSO_FILL_TYPE.GRADIENT: self.__gradient_id += 1 gradient = Gradient(self.__dwg, self.__gradient_id, shape, self.__colour_map) svg_path.attribs['fill'] = gradient.url elif shape.fill.type is None: svg_path.attribs['fill'] = '#FF0000' svg_path.attribs['opacity'] = 1.0 elif shape.fill.type == MSO_FILL_TYPE.GROUP: # WIP Needs to get group's fill print('Group fill ignored for ', shape.name) elif shape.fill.type != MSO_FILL_TYPE.BACKGROUND: print('Unsupported fill type: {}'.format(shape.fill.type)) if shape.line.fill.type == MSO_FILL_TYPE.SOLID: svg_path.attribs['stroke'] = self.__colour_map.lookup( shape.line.color) alpha = shape.line.fill.fore_color.alpha if alpha < 1.0: svg_path.attribs['stroke-opacity'] = alpha elif shape.line.fill.type is None: svg_path.attribs['stroke'] = '#000000' elif shape.line.fill.type != MSO_FILL_TYPE.BACKGROUND: print('Unsupported line fill type: {}'.format( shape.line.fill.type)) stroke_width = points_to_pixels( max(Length(shape.line.width).pt, MIN_STROKE_WIDTH)) svg_path.attribs['stroke-width'] = stroke_width if shape.line.dash_style is not None: if shape.line.dash_style == MSO_LINE_DASH_STYLE.DASH: svg_path.attribs['stroke-dasharray'] = 4 * stroke_width elif shape.line.dash_style == MSO_LINE_DASH_STYLE.DASH_DOT: svg_path.attribs[ 'stroke-dasharray'] = '{} {} {} {}'.format( 4 * stroke_width, stroke_width, stroke_width, stroke_width) elif shape.line.dash_style == MSO_LINE_DASH_STYLE.LONG_DASH: svg_path.attribs['stroke-dasharray'] = '{} {}'.format( 4 * stroke_width, stroke_width) elif shape.line.dash_style == MSO_LINE_DASH_STYLE.SQUARE_DOT: svg_path.attribs['stroke-dasharray'] = '{} {}'.format( 2 * stroke_width, stroke_width) elif shape.line.dash_style != MSO_LINE_DASH_STYLE.SOLID: print('Unsupported line dash style: {}'.format( shape.line.dash_style)) ## WIP if 'type' in shape.line.headEnd or 'type' in shape.line.tailEnd: ## WIP svg_path.set_markers((marker_id(shape.line.headEnd, 'head'), ## WIP None, ## WIP marker_id(shape.line.tailEnd, 'tail'))) svg_parent.add(svg_path)
def it_can_self_convert_to_convenient_units(self, units_fixture): emu, units_prop_name, expected_length_in_units = units_fixture length = Length(emu) length_in_units = getattr(length, units_prop_name) assert length_in_units == expected_length_in_units
pic_height = img.shape[1] pic = slide.shapes.add_picture(pic_save_path, left, top, height=height) left = left + pic_width * height / pic_height os.remove(pic_save_path) else: width = Inches(len(row) / 4 + 2) print(width) print(Inches(12)) if left + width > Inches(12): use_width = Inches(12) - left print(use_width) from pptx.util import Length use_word = Length(4 * use_width).inches print(">>>>>>>>>>>>>>>>>use_word:" + str(use_word)) txBox = slide.shapes.add_textbox( left, top, use_width, height) tf = txBox.text_frame print(row) tf.text = row[0:int(use_word)] left = Inches(0.5) top = top + Inches(0.5) other_word_num = len(row) - use_word if other_word_num % 36 == 0: perform = other_word_num / 36 else: perform = int(other_word_num / 36) + 1 i = 0 while i < perform: