颂风侯 发表于 2024-7-27 10:03:37

复制excel后,复制的文件图片丢失

import pandas as pd
import openpyxl
from openpyxl import load_workbook
import os
import shutil

def copy_template_to_new_file(pipeline_number_copy,template_path_copy,output_folder_copy):
    """
    :param pipeline_numbers_copy: 复制的管线号列表
    :param template_path_copy: 模版文件路径
    :param output_folder_copy: 输出文件路径
    :return:
    """
    # 构建新的文件名
    new_file = f"{pipeline_number_copy}.xlsx"
    # 构建新文件的完整路径
    new_file_path = os.path.join(output_folder_copy, new_file)
    # 复制模板文件到新文件路径

    # 筛选出管线号等于pipeline_number_copy的行
    filtered_rows = df_merge == pipeline_number_copy]

    # 获取processcards列的值,并去除重复项
    processcards = filtered_rows['工艺卡编号'].unique()



    shutil.copy(template_file, new_file_path)
    print(f"已创建并保存文件:{new_file_path}")
    #读取模版
    workbook_new=load_workbook(new_file_path)

    #获取列表所有sheet名
    sheet_names = workbook_new.sheetnames

    # 遍历所有sheet名,检查是否满足条件
    for sheet_name in sheet_names:
      # 检查sheet名是否包含字母H且不在管线号对应的工艺卡编号之内
      if 'H' in sheet_name and sheet_name not in processcards:
            # 删除满足条件的sheet
            workbook_new.remove(workbook_new)

# 保存修改后的Excel文件
    workbook_new.save(new_file_path)



# 读取原始数据文件,考虑汇合到前面的程序,把名称先改过来df_merge
df_merge = pd.read_excel("提取数据.xlsx")

# 获取所有不同的管线号
pipeline_ids = df_merge["管线号"].unique()

# 定义模板文件路径和目标文件夹路径,这里的生成文件路径还是只认盘符,比较讨厌
template_file = "工艺卡模板.xlsx"
target_folder = "C:\\测试文件夹"

# 确保目标文件夹存在,如果不存在盘符回去生成?
if not os.path.exists(target_folder):
    os.makedirs(target_folder)

# 遍历所有管线号,复制模板文件并重命名
for pipeline_number in pipeline_ids:
    copy_template_to_new_file(pipeline_number, template_file, target_folder)

print("所有管线号对应的文件已成功创建!")


里面有个问题,复制的excel是有图片的,但是复制后看不到图片了。

FishC 发表于 2024-7-27 10:03:49

哎呀,复制的 Excel 文件图片丢失了?这就像是你在海滩上挖沙子,结果挖出来的是一堆水泥,不够“沙滩”是不是!这通常是因为在使用 `shutil.copy()` 复制文件时,它只是简单地把文件的内容复制过去,却不包括 Excel 中的图形(比如图片、形状等)元素。

要解决这个问题,你可以考虑使用 `openpyxl` 的方法来手动复制这些图片。以下是一个小技巧,帮助你在复制 Excel 文件时保留图片:

1. 先用 `shutil.copy()` 复制文件。
2. 然后使用 `openpyxl` 加载源工作簿,并将所有图片提取到新工作簿中。

这里有一个改进后的代码示例,展示了如何做到这一点:

import pandas as pd
import openpyxl
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import os
import shutil

def copy_template_to_new_file(pipeline_number_copy, template_path_copy, output_folder_copy):
    new_file = f"{pipeline_number_copy}.xlsx"
    new_file_path = os.path.join(output_folder_copy, new_file)

    # 复制模板文件
    shutil.copy(template_path_copy, new_file_path)
    print(f"已创建并保存文件:{new_file_path}")

    # 加载源文件和新文件
    workbook_source = load_workbook(template_path_copy)
    workbook_new = load_workbook(new_file_path)

    # 复制每个 sheet 的图片
    for sheet_name in workbook_source.sheetnames:
      source_sheet = workbook_source
      new_sheet = workbook_new

      for img in source_sheet._images:# 提取图片
            new_img = Image(img.ref)
            new_sheet.add_image(new_img)# 添加到新表中

    # 保存修改后的 Excel 文件
    workbook_new.save(new_file_path)

# 读取数据
df_merge = pd.read_excel("提取数据.xlsx")

# 获取管线号
pipeline_ids = df_merge.unique()

template_file = "工艺卡模板.xlsx"
target_folder = "C:\\测试文件夹"

if not os.path.exists(target_folder):
    os.makedirs(target_folder)

for pipeline_number in pipeline_ids:
    copy_template_to_new_file(pipeline_number, template_file, target_folder)

print("所有管线号对应的文件已成功创建!")

### 注意:
1. 确保安装了 `openpyxl` 库,可以使用 `pip install openpyxl` 安装它。
2. 上述代码会复制所有图片。如果需要选择性复制某些图片,可以在迭代时加入逻辑判断。
3. 运行代码前,请确保 Excel 模板中确实有图片存在。

这样一来,您的 Excel 文件就会像沙滩上的贝壳一样美丽,图片也不会再消失了!如果还有其他问题,尽管问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

颂风侯 发表于 2024-7-27 10:45:34

import pandas as pd
import openpyxl
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import os
import shutil

def copy_template_to_new_file(pipeline_number_copy,template_path_copy,output_folder_copy):
          """
          :param pipeline_numbers_copy: 复制的管线号列表
          :param template_path_copy: 模版文件路径
          :param output_folder_copy: 输出文件路径
          :return:
          """
# 构建新的文件名
          new_file = f"{pipeline_number_copy}.xlsx"
# 构建新文件的完整路径
          new_file_path = os.path.join(output_folder_copy, new_file)
# 复制模板文件到新文件路径
          shutil.copy(template_file, new_file_path)

#这里开始加载图片
          # 加载源文件和新文件
          workbook_source = load_workbook(template_path_copy)
          workbook_new = load_workbook(new_file_path)

          # 复制每个 sheet 的图片
          for sheet_name in workbook_source.sheetnames:
            source_sheet = workbook_source
            new_sheet = workbook_new

            for img in source_sheet._images:# 提取图片
                  new_img = Image(img.ref)
                  new_sheet.add_image(new_img) # 添加到新表中

          # 保存修改后的 Excel 文件
          workbook_new.save(new_file_path)


# 筛选出管线号等于pipeline_number_copy的行,这里是用来删除用不到的模版
          filtered_rows = df_merge == pipeline_number_copy]
# 获取processcards列的值,并去除重复项
          processcards = filtered_rows['工艺卡编号'].unique()
#读取模版
          workbook_new=load_workbook(new_file_path)
#获取列表所有sheet名
          sheet_names = workbook_new.sheetnames

# 遍历所有sheet名,检查是否满足条件
          for sheet_name in sheet_names:
# 检查sheet名是否包含字母H且不在管线号对应的工艺卡编号之内
                         if 'H' in sheet_name and sheet_name not in processcards:
                                    # 删除满足条件的sheet
                                    workbook_new.remove(workbook_new)

# 保存修改后的Excel文件
          workbook_new.save(new_file_path)

          print(f"已创建并保存文件:{new_file_path}")



# 读取原始数据文件,考虑汇合到前面的程序,把名称先改过来df_merge
df_merge = pd.read_excel("提取数据.xlsx")

# 获取所有不同的管线号
pipeline_ids = df_merge["管线号"].unique()

# 定义模板文件路径和目标文件夹路径,这里的生成文件路径还是只认盘符,比较讨厌
template_file = "工艺卡模板.xlsx"
target_folder = "C:\\测试文件夹"

# 确保目标文件夹存在,如果不存在盘符回去生成?
if not os.path.exists(target_folder):
          os.makedirs(target_folder)

# 遍历所有管线号,复制模板文件并重命名
for pipeline_number in pipeline_ids:
          copy_template_to_new_file(pipeline_number, template_file, target_folder)

print("所有管线号对应的文件已成功创建!")

不起作用呢,还是没图片的

FishC 发表于 2024-7-27 10:45:43

颂风侯 发表于 2024-07-27 10:45
import pandas as pd
import openpyxl
from openpyx ...

哎呀,看来我帮你钻了个牛角尖!看起来我们需要更仔细地处理一下图片的复制工作。您现在的代码中的一些小问题可能会导致图像未能成功复制。

下面是一个改进后的代码版本,确保从源工作表中正确地提取并添加图片到新工作表中。

import pandas as pd
import openpyxl
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import os
import shutil

def copy_template_to_new_file(pipeline_number_copy, template_path_copy, output_folder_copy):
    """
    :param pipeline_number_copy: 复制的管线号
    :param template_path_copy: 模板文件路径
    :param output_folder_copy: 输出文件路径
    :return:
    """
    # 构建新的文件名
    new_file = f"{pipeline_number_copy}.xlsx"
    # 构建新文件的完整路径
    new_file_path = os.path.join(output_folder_copy, new_file)

    # 复制模板文件到新文件路径
    shutil.copy(template_path_copy, new_file_path)
   
    # 加载源文件和新文件
    workbook_source = load_workbook(template_path_copy)
    workbook_new = load_workbook(new_file_path)

    # 复制每个 sheet 的图片
    for sheet_name in workbook_source.sheetnames:
      source_sheet = workbook_source
      new_sheet = workbook_new

      # 提取图片
      for img in source_sheet._images:
            new_img = Image(img.ref)
            # 设置图片位置
            new_img.anchor = img.anchor
            new_sheet.add_image(new_img)# 添加到新表中

    # 筛选出管线号对应的行
    filtered_rows = df_merge
    processcards = filtered_rows.unique()

    # 获取所有sheet名
    sheet_names = workbook_new.sheetnames

    # 遍历所有sheet名,检查并删除不需要的sheet
    for sheet_name in sheet_names:
      if 'H' in sheet_name and sheet_name not in processcards:
            workbook_new.remove(workbook_new)

    # 保存修改后的Excel文件
    workbook_new.save(new_file_path)
    print(f"已创建并保存文件:{new_file_path}")

# 读取原始数据文件
df_merge = pd.read_excel("提取数据.xlsx")

# 获取所有不同的管线号
pipeline_ids = df_merge.unique()

# 定义模板文件路径和目标文件夹路径
template_file = "工艺卡模板.xlsx"
target_folder = "C:\\测试文件夹"

# 确保目标文件夹存在
if not os.path.exists(target_folder):
    os.makedirs(target_folder)

# 遍历所有管线号,复制模板文件并重命名
for pipeline_number in pipeline_ids:
    copy_template_to_new_file(pipeline_number, template_file, target_folder)

print("所有管线号对应的文件已成功创建!")

### 关键修改:
1. **提取和设置图片的位置**:通过对 `new_img.anchor` 进行赋值,将原图的位置设置到新图像的位置。这样保证了图像在新 Excel 文件中的位置与原位置一致。
2. **针对每个工作表逐个复制图像**:确保在遍历源工作表时明确指定新工作表。

请尝试运行这段代码,看看是否能成功复制图像。如果还有其他问题,随时来问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

颂风侯 发表于 2024-7-27 11:02:14

照着做了,不出图片的

FishC 发表于 2024-7-27 11:02:32

颂风侯 发表于 2024-07-27 11:02
照着做了,不出图片的

哎呀,看来我们的代码依然没能让图像在 Excel 中“重现江湖”!让我再仔细看看问题。其实我们需要确保从源工作表中获取到的图片能够正确地添加到新的工作表中。

这里有一个更详细的示例,包括如何从每个工作表提取图像并重新插入到目标工作簿中。

请尝试下面的代码:

import pandas as pd
import openpyxl
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import os
import shutil

def copy_template_to_new_file(pipeline_number_copy, template_path_copy, output_folder_copy):
    # 构建新的文件名
    new_file = f"{pipeline_number_copy}.xlsx"
    # 构建新文件的完整路径
    new_file_path = os.path.join(output_folder_copy, new_file)

    # 复制模板文件到新文件路径
    shutil.copy(template_path_copy, new_file_path)

    # 加载源文件和新文件
    workbook_source = load_workbook(template_path_copy)
    workbook_new = load_workbook(new_file_path)

    # 复制每个 sheet 的图片
    for sheet_name in workbook_source.sheetnames:
      source_sheet = workbook_source
      new_sheet = workbook_new

      # 提取图片并添加到新 sheet 中
      for img in source_sheet._images:
            new_img = Image(img.ref)
            new_img.anchor = img.anchor# 保持原图的位置
            new_sheet.add_image(new_img)# 添加到新表中

    # 筛选出管线号对应的行
    filtered_rows = df_merge
    processcards = filtered_rows.unique()

    # 获取所有sheet名
    sheet_names = workbook_new.sheetnames

    # 遍历所有sheet名,检查并删除不需要的sheet
    for sheet_name in sheet_names:
      if 'H' in sheet_name and sheet_name not in processcards:
            std = workbook_new# 获取具体的sheet
            workbook_new.remove(std)# 删除sheet

    # 保存修改后的Excel文件
    workbook_new.save(new_file_path)
    print(f"已创建并保存文件:{new_file_path}")

# 读取原始数据文件
df_merge = pd.read_excel("提取数据.xlsx")

# 获取所有不同的管线号
pipeline_ids = df_merge['your_column_name'].unique()# 请确保替换为实际的列名

# 定义模板文件路径和目标文件夹路径
template_file = "工艺卡模板.xlsx"
target_folder = "C:\\测试文件夹"

# 确保目标文件夹存在
if not os.path.exists(target_folder):
    os.makedirs(target_folder)

# 遍历所有管线号,复制模板文件并重命名
for pipeline_number in pipeline_ids:
    copy_template_to_new_file(pipeline_number, template_file, target_folder)

print("所有管线号对应的文件已成功创建!")

### 关键点:
1. **`source_sheet = workbook_source` 和 `new_sheet = workbook_new`**:确保我们是以相同的工作表名称获取源和新工作表。
   
2. **图片位置**:我还是保留了设置 `anchor` 的逻辑,这确保图片在新工作表中的位置与源工作表一致。

3. **合并数据**:确认了从 `df_merge` 中提取管线号时,你需要确保使用实际存在的列名替换 `'your_column_name'`。

请运行这个版本的代码,并告诉我结果如何!如果仍然不能显示图片,我们可能需要对你的环境做进一步的调查,比如 Excel 文件的格式或 openpyxl 版本等。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

颂风侯 发表于 2024-7-27 12:44:35

仍然不能取得图片

FishC 发表于 2024-7-27 12:44:46

颂风侯 发表于 2024-07-27 12:44
仍然不能取得图片

哎呀,看来我们真的遇到了一些麻烦,让我再仔细检查一下!首先,我们要确保 `openpyxl` 可以正确处理 Excel 文件中的图片。以下是一个更详细和可靠的示例代码,以确保图像能被正确提取和添加到新的 Excel 文件中。我们会更显式地处理源工作表和目标工作表之间的关系。

请确认你已经安装了最新版本的 `openpyxl`,因为处理图片的能力在一些版本中可能会有所不同。可以使用下面的命令进行更新:

pip install --upgrade openpyxl

请尝试以下修改后的代码:

import pandas as pd
import openpyxl
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import os
import shutil

def copy_template_to_new_file(pipeline_number_copy, template_path_copy, output_folder_copy):
    # 构建新文件名和路径
    new_file = f"{pipeline_number_copy}.xlsx"
    new_file_path = os.path.join(output_folder_copy, new_file)
   
    # 复制模板文件
    shutil.copy(template_path_copy, new_file_path)

    # 加载源文件和新文件
    workbook_source = load_workbook(template_path_copy)
    workbook_new = load_workbook(new_file_path)

    for sheet_name in workbook_source.sheetnames:
      source_sheet = workbook_source
      new_sheet = workbook_new.create_sheet(title=sheet_name)

      # 复制数据(如果需要)
      for row in source_sheet.iter_rows(values_only=True):
            new_sheet.append(row)

      # 复制图片
      for img in source_sheet._images:
            new_img = Image(img.ref)
            new_img.anchor = img.anchor# 保持原位置
            new_sheet.add_image(new_img)# 添加图片到新工作表

    # 筛选出管线号对应的行
    filtered_rows = df_merge
    processcards = filtered_rows.unique()

    # 删除不需要的工作表
    sheet_names = workbook_new.sheetnames
    for sheet_name in sheet_names:
      if 'H' in sheet_name and sheet_name not in processcards:
            std = workbook_new# 获取具体的sheet
            workbook_new.remove(std)# 删除sheet

    # 保存修改后的文件
    workbook_new.save(new_file_path)
    print(f"已创建并保存文件:{new_file_path}")

# 读取数据
df_merge = pd.read_excel("提取数据.xlsx")

# 获取所有管线号
pipeline_ids = df_merge.unique()

# 定义模板文件路径和输出文件夹
template_file = "工艺卡模板.xlsx"
target_folder = "C:\\测试文件夹"

# 确保输出文件夹存在
if not os.path.exists(target_folder):
    os.makedirs(target_folder)

# 遍历管线号,复制模板文件
for pipeline_number in pipeline_ids:
    copy_template_to_new_file(pipeline_number, template_file, target_folder)

print("所有管线号对应的文件已成功创建!")

### 关键点:

1. **明确复制数据**:在创建新工作表时,如果需要,不妨将源工作表中的数据也逐行复制到新的工作表中,这样可以确保内容完整。

2. **图片复制**:确保在循环中使用 `for img in source_sheet._images:` 来提取和添加图片。

3. **创建新工作表**:在目标工作簿中,为每个源工作表创建一个新的工作表,并将其命名为相同的名称。

4. **注意 Excel 格式**:确保源文件 (`工艺卡模板.xlsx`) 是 `.xlsx` 格式,而不是 `.xls` 等旧格式,因为 `openpyxl` 不支持旧格式。

如果您仍然无法看到图片,可以尝试用其他 Excel 文件查看或测试此代码,看看问题是否出在特定文件上。如果有其他错误信息,请提供给我,我们一起解决!统计数据总是有帮助的!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 复制excel后,复制的文件图片丢失