16.12.2019

Copy data from one Excel workbook to a new workbook with Python & OpenPyXL

I got an excellent question in my OpenPyXL course. The question was how to transfer data from one Excel workbook to another with OpenPyXL. Transferring data only is easier, as there is no need to worry about the formatting of cells and sheets. The complete code is available at the bottom of this post.

Mission statement

The question was how to copy data from one sheet in a workbook to several other sheets in a newly created workbook. The source workbook is WB1 with the source sheet WS1. The source sheet has 1000 rows of data. The data shall be copied to the new workbook WB2 and the sheets WS1 to WS10.

  • Copy the first 100 rows data and paste it into sheet WS1
  • Copy the next 200 rows data and paste it into sheet WS2
  • Copy the next 50 rows data and paste it into sheet WS3
  • Copy the next 300 rows data and paste it into sheet WS4
  • Copy the next 350 rows data and paste it into sheet WS4

Imports and loading workbook

To copy the values we need to import Workbook and load_workbook from the OpenPyXL library. We can now load our existing workbook, WB1. WB1 = load_workbook("Source.xlsx", data_only=True). The next thing we need to do is set which sheet we are going to copy the data from. We name the sheet WB1_WS1 WB1_WS1 = WB1["WS1"] . After that we are ready to create a new workbook with WB2 = Workbook(). Notice the brackets for the method.

Creating sheets

The question stated that 10 sheets should be created, with the names WS1 to WS10. We can create the sheets with a for loop. Each sheet is created with create_sheet(f"WS{i}"). Notice the usage of Pythons f-string. We then remove the default created sheet, Sheet1. We could also of course have renamed it.

# Create WB2 sheets WS1-WS10
for i in range(1, 11):
    WB2.create_sheet(f"WS{i}")

# delete first sheet
WB2.remove(WB2.worksheets[0])

Copy preparations

The next thing is to create a list for holding our copy ranges, and also which sheets we want to copy the data to. The copy_ranges list holds how many rows we need to copy from the source sheet to the sheets defined in copy_to_sheets.

# Define the copy ranges and sheets
copy_ranges = [100, 200, 50, 300, 350]
copy_to_sheets = ["WS1", "WS2", "WS3", "WS4", "WS4"]

Copying the data

We start with a for loop, that iterates through the copy_ranges list. for i in range( len(copy_ranges)): We then specify which sheet is in turn for copying ws = WB2[ copy_to_sheets[i] ]. Notice how we specify the sheet with the copy_to_sheets list. When i is 1 we select WS1 and so on. We also initialize our row_offset to 1 so that we can keep track of which rows to copy next. We then set the row_offset with yet another for loop. We increase the offset i times with the corresponding values from copy_ranges.

for s in range(i):
    offset += copy_ranges[s]

Now it is time to fill our sheets with data! we traverse through our offset range with a for loop and set the values of the corresponding sheet. First we get the row with for j in range(offset, offset + copy_ranges[i]):. Next up are the cells in each row:

for row in WB1_WS1.iter_rows(min_row=j, max_row=j, min_col=1, max_col=WB1_WS1.max_column):.

We get the values for values_row with a list comprehension [cell.value for cell in row]. Finally, we append the row to the sheet with ws.append(values_row).

# Copy the row with the help of iter_rows, append the row
for j in range(offset,  offset + copy_ranges[i]):
    #if j == 0:
    #    continue
    for row in WB1_WS1.iter_rows(min_row=j, max_row=j, min_col=1, max_col=WB1_WS1.max_column):
        values_row = [cell.value for cell in row]
    ws.append(values_row)

To wrap up, we save the workbook: WB2.save("WB2.xlsx")

That's it! Please comment below if you have questions or any feedback. See you later!

Use this link, Control Excel with Python & OpenPyXL or this code SAVEOPENPYXL to get the course for a discount on Udemy.com

This image has an empty alt attribute; its file name is OpenPyXL_course-1024x407.png

The code

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
Could you please suggest  how to copy the data from on work book to other book with specified rows
Source: Excel work book "WB1" having work sheet "WS1", This sheet  having 1000 rows of data
Destination: New work book 'WB2' and  work sheets WS1,WS2...WS10
Could you please suggest the code for following condition:
Copy the first 100 rows data and paste it WS1 sheet
Copy the next 200 rows data and paste it WS2 sheet
Copy the next 50 rows data and paste it WS3 sheet
Copy the next 300 rows data and paste it WS4 sheet
Copy the next 350 rows data and paste it WS4 sheet
"""

from openpyxl import Workbook, load_workbook

WB1 = load_workbook("Source.xlsx", data_only=True)
WB1_WS1 = WB1["WS1"]
WB2 = Workbook()

# Create WB2 sheets WS1-WS10
for i in range(1, 11):
    WB2.create_sheet(f"WS{i}")

# delete first sheet
WB2.remove(WB2.worksheets[0])

# Define the copy ranges and sheets
copy_ranges = [100, 200, 50, 300, 350]
copy_to_sheets = ["WS1", "WS2", "WS3", "WS4", "WS4"]

# Copy the values from the rows in WB1 to WB2.
for i in range( len(copy_ranges)):
    # Set the sheet to copy to
    ws = WB2[ copy_to_sheets[i] ]
    # Initialize row offset
    offset = 1
    # Set the row offset
    for s in range(i):
        offset += copy_ranges[s]

    # Copy the row with the help of iter_rows, append the row
    for j in range(offset,  offset + copy_ranges[i]):
        #if j == 0:
        #    continue
        for row in WB1_WS1.iter_rows(min_row=j, max_row=j, min_col=1, max_col=WB1_WS1.max_column):
            values_row = [cell.value for cell in row]
        ws.append(values_row)

# Save the workbook
WB2.save("WB2.xlsx")

Leave a Reply

Your email address will not be published.

linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram