ソースを参照

excel截图功能,linux可用

ClownHe 1 年間 前
コミット
fcb7bdc597
1 ファイル変更278 行追加0 行削除
  1. 278 0
      cppc_python脚本/服务器脚本/demo_数据表截图.py

+ 278 - 0
cppc_python脚本/服务器脚本/demo_数据表截图.py

@@ -0,0 +1,278 @@
+# -*- codeing = utf-8 -*-
+# @Time : 2024/5/20 18:44
+# @Author : Clown
+# @File : demo_数据表截图.py
+# @Software : PyCharm
+import os.path
+import uuid
+from io import BytesIO
+from typing import Union
+
+import xlwings as xw
+from PIL import ImageGrab,ImageOps
+from spire.xls import *
+
+from openpyxl import load_workbook
+from PIL import Image
+from PIL import ImageDraw
+from PIL import ImageFont
+import tempfile
+from wcwidth import wcswidth
+
+# 以下仅使用于安装了Microsoft的设备上
+def excel_grab(excel_path, sheet_name: Union[str, int] = 0, cell_area=None, pic_path=None, visible=False, saved=True):
+    """
+    Excel指定区域截图
+    :param excel_path: Excel文件路径
+    :param sheet_name: 工作表名称或索引,0即第一张工作表
+    :param cell_area: 截图区域,默认None。'A2:N17', 不指定时获取有内容的区域截图
+    :param pic_path: 截图文件路径,png格式
+    :param visible: 截图时是否打开显示Excel
+    :param saved: 是否将截图保存到本地
+    :return: png路径 或 图片的bytes
+    """
+    app = xw.App(visible=visible, add_book=False)
+    wb = app.books.open(excel_path)
+    if isinstance(sheet_name, str):
+        sheet = wb.sheets(sheet_name)
+    else:
+        sheet = wb.sheets[sheet_name]
+    if cell_area:
+        pic_area = sheet[cell_area]
+    else:
+        pic_area = sheet.used_range  # 获取有内容的range
+        pic_area.autofit() #自适应调整列宽和行高
+        # Borders(11) 内部垂直边线。
+        pic_area.api.Borders(11).LineStyle = 1
+        pic_area.api.Borders(11).Weight = 3
+
+        # Borders(12) 内部水平边线。
+        pic_area.api.Borders(12).LineStyle = 1
+        pic_area.api.Borders(12).Weight = 3
+    try:
+        pic_area.api.CopyPicture()  # 复制图片区域
+        sheet.api.Paste()
+        pic = sheet.pictures[0]  # 当前图片
+        pic.api.Copy()
+        pic.delete()  # 删除sheet上的图片
+    except Exception as e:
+        return f'区域【{cell_area}】截图失败,错误:{e}'
+    finally:
+        wb.close()
+        app.quit()
+
+    try:
+        img = ImageGrab.grabclipboard()  # 获取剪贴板的图片数据
+        img = ImageOps.expand(img, border = 10, fill = 'white') #背景改成白色
+    except Exception as e:
+        return f'区域【{cell_area}】从剪贴板获取截图失败,错误:{e}'
+    if saved:
+        if not pic_path:
+            pic_path = f'{os.path.splitext(excel_path)[0]}_{uuid.uuid4().hex[:10]}.png'
+            print(pic_path)
+        img.save(pic_path)
+    else:
+        f = BytesIO()
+        img.save(f, 'png')
+        img_data = f.getvalue()
+        f.close()
+    return pic_path if saved else img_data
+
+def excel_to_pic(excel_path):
+    import pandas as pd
+    import matplotlib.pyplot as plt
+    from pandas.plotting import table
+    from PIL import Image
+    from io import BytesIO
+
+    from pylab import mpl
+
+    mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 指定默认字体:解决plot不能显示中文问题
+    mpl.rcParams['axes.unicode_minus'] = False
+
+    xls = pd.ExcelFile(excel_path)
+    j = 0
+    for sheet_name in xls.sheet_names:
+        # 读取工作表数据
+        df = pd.read_excel(xls, sheet_name = sheet_name)
+        # 将缺失值转为空字符串,避免表格中出现NaN
+        df = df.applymap(lambda x: str(x) if pd.notna(x) else '')
+        # 创建一个样式对象
+
+        print("正在处理 %s 表格" % sheet_name)
+        j = j + 1
+
+        if df.shape[0] > 150:  # 假设以100行作为一个分割点
+
+            df_split = [df[i:i + 150] for i in range(0, df.shape[0], 150)]
+
+            for i, data in enumerate(df_split):
+                fig = plt.figure(figsize = (9, 26), dpi = 200)
+                ax = fig.add_subplot(111, frame_on = False)
+
+                # 隐藏x轴 y轴
+                ax.xaxis.set_visible(False)  # hide the x axis
+                ax.yaxis.set_visible(False)  # hide the y axis
+
+                fig.tight_layout()
+                # 如果数据是图片,则保存为图片,否则执行表格处理
+                if isinstance(data.iloc[0, 0], Image.Image):  # 检查数据是否为图片
+                    img = data.iloc[:, 0].apply(lambda x: x.tobytes())  # 将图片转换为字节流
+                    img_buffer = BytesIO()
+                    img_buffer.write(img.values.tobytes())  # 将字节流转为BytesIO对象
+                    img = Image.open(img_buffer)  # 将BytesIO对象转为图片
+                    img.save( str(j) + '_' + str(i) + '!' + sheet_name + '.png')  # 保存图片
+                else:
+
+                    ax.table(cellText = data.values, colLabels = data.columns, cellLoc = 'center', loc = 'center')
+                    ax.set_title(sheet_name, fontsize = 12, loc = 'left')
+                    # ax.text(0, 1, sheet_name, ha='left', va='center', fontsize=12, transform=ax.transAxes)
+                    plt.savefig( str(j) + '_' + str(i) + '!' + sheet_name + '.jpg')
+                plt.close(fig)
+                print("已完成 %s 表格处理" % sheet_name)
+        elif df.shape[0] > 50:
+            if isinstance(df.iloc[0, 0], Image.Image):  # 检查数据是否为图片
+                img = df.iloc[:, 0].apply(lambda x: x.tobytes())  # 将图片转换为字节流
+                img_buffer = BytesIO()
+                img_buffer.write(img.values.tobytes())  # 将字节流转为BytesIO对象
+                img = Image.open(img_buffer)  # 将BytesIO对象转为图片
+                img.save(str(j) + '!' + sheet_name + '.png')  # 保存图片
+            else:
+
+                fig = plt.figure(figsize = (9, 10), dpi = 500)
+                ax = fig.add_subplot(111, frame_on = False)
+                ax.set_title(sheet_name, fontsize = 12, loc = 'left')
+                # ax.text(0, 0.8, sheet_name, ha='left', va='center', fontsize=12, transform=ax.transAxes)
+                table1 = ax.table(cellText = df.values, colLabels = df.columns, cellLoc = 'center', loc = 'center')
+                table1.auto_set_font_size(True)  # 禁用自动设置字体大小
+                table1.set_fontsize(14)  # 设置字体大小为12
+                ax.xaxis.set_visible(False)  # hide the x axis
+                ax.yaxis.set_visible(False)  # hide the y axis
+                fig.tight_layout()
+                plt.savefig( str(j) + '!' + sheet_name + '.jpg')
+            plt.close(fig)
+            print("已完成 %s 表格处理" % sheet_name)
+
+
+        else:
+            if isinstance(df.iloc[0, 0], Image.Image):  # 检查数据是否为图片
+                img = df.iloc[:, 0].apply(lambda x: x.tobytes())  # 将图片转换为字节流
+                img_buffer = BytesIO()
+                img_buffer.write(img.values.tobytes())  # 将字节流转为BytesIO对象
+                img = Image.open(img_buffer)  # 将BytesIO对象转为图片
+                img.save( str(j) + '!' + sheet_name + '.png')  # 保存图片
+            else:
+
+                fig = plt.figure(figsize = (9, 6), dpi = 500)
+                ax = fig.add_subplot(111, frame_on = False)
+                ax.set_title(sheet_name, fontsize = 12, loc = 'left')
+                # 设置标题在x,y轴上位置,字体
+                # ax.text(0, 0.8, sheet_name, ha='left', va='center', fontsize=12, transform=ax.transAxes)
+                table1 = ax.table(cellText = df.values, colLabels = df.columns, cellLoc = 'center', loc = 'center')
+                table1.auto_set_font_size(True)  # 禁用自动设置字体大小
+                table1.set_fontsize(14)  # 设置字体大小为12
+
+                ax.xaxis.set_visible(False)  # hide the x axis
+                ax.yaxis.set_visible(False)  # hide the y axis
+
+                # fig.tight_layout()
+                plt.savefig( str(j) + '!' + sheet_name + '.jpg')
+            plt.close(fig)
+            print("已完成 %s 表格处理" % sheet_name)
+
+def excel_to_img(excel_path):
+
+
+    # 创建Workbook对象
+    workbook = Workbook()
+
+    # 载入Excel文件
+    workbook.LoadFromFile(excel_path)
+
+    # 获取工作表
+    sheet = workbook.Worksheets.get_Item(0)
+
+    # 移除页边距
+    pageSetup = sheet.PageSetup
+    pageSetup.TopMargin = 0
+    pageSetup.BottomMargin = 0
+    pageSetup.LeftMargin = 0
+    pageSetup.RightMargin = 0
+
+    # 将工作表转换为图片
+    image = sheet.ToImage(sheet.FirstRow, sheet.FirstColumn, sheet.LastRow, sheet.LastColumn)
+
+    # 保存图片
+    image.Save("工作表转图片.png")
+
+    workbook.Dispose()
+
+def excel_to_img_linux(excel_path):
+    # 加载Excel文件
+    wb = load_workbook(excel_path)
+    sheet = wb.active
+
+    # 单元格的行高和列宽
+    row_height = 20
+    column_width = 10
+
+    # 扫描表格尺寸
+    row_size = {}
+    for i in range(sheet.max_column):
+        row_size[str(i)] = 0
+    print(row_size)
+    for row in sheet.iter_rows(min_row = 1, min_col = 1, max_col = sheet.max_column, max_row = sheet.max_row):
+        n = 0
+        for cell in row:
+            text = str(cell.value) if cell.value is not None else ''
+            if row_size[str(n)] <= wcswidth(text):
+                row_size[str(n)] = wcswidth(text)
+            n += 1
+    print(row_size)
+    img_width = 0
+    for key, v in row_size.items():
+        img_width = img_width + v
+    print(img_width)
+
+    if 1 == 1:
+        # 创建一个图像,大小根据单元格大小进行调整
+        img_width = column_width * img_width
+        img_height = row_height * (sheet.max_row + 1)
+        img = Image.new('RGB', (img_width, img_height), color = 'white')
+
+        # 设置字体
+        font = ImageFont.truetype('E:/chrome下载文件/simsun.ttc', 16)
+        draw = ImageDraw.Draw(img)
+
+        # 绘制网路线
+        grid_color = (128, 128, 128)
+        for row_line_y in range(sheet.max_row + 1):
+            draw.line([(0, row_height * row_line_y), (img_width, row_height * row_line_y)], fill = grid_color)  # 画横线
+
+        img_width = 0
+        for key, v in row_size.items():
+            draw.line([(img_width, 0), (img_width, row_height * sheet.max_row)], fill = grid_color)  # 画纵线
+            img_width = img_width + (v * column_width)
+
+        # 绘制单元格内容
+        for row in sheet.iter_rows(min_row = 1, min_col = 1, max_col = sheet.max_column, max_row = sheet.max_row):
+            n = 0
+            m = 4
+            for cell in row:
+                text = str(cell.value) if cell.value is not None else ''
+                draw.text((m, row_height * (cell.row - 1) + 2), text, font = font, fill = (0, 0, 0))
+                m = m + (column_width * row_size[str(n)])
+                n += 1
+
+        # 保存图片
+        img.save('output.png')
+
+
+if __name__ == '__main__':
+    excel_path = r'C:\Users\ClownHe\Desktop\店务通数据\2024-05-11至2024-05-17发货单(supplier_split).xlsx'
+    # excel_grab(excel_path)
+    # 使用函数
+    output_path = 'output_image.png'  # 输出图片的路径
+    # excel_to_pic(excel_path)
+    # excel_to_img(excel_path)
+    excel_to_img_linux(excel_path)