'Copy Filtered Rows in MS Excel with Python

A small introduction: I need a script that takes an Excel and based on a json that I give to him it sends a Mail to a list of person with attached the same Excel filtered(Every person has his personal filter option) and printed as pdf AND a copy of the excel where only the filtered cells are accessible.

from numpy import datetime64
import xlwings as xw
import pandas as pd
import os.path as path
import win32com.client as win32
import glob
import numpy as np
import json
import codecs

xw.interactive = False

file = glob.glob("*.xlsm")[0]
with open(path.abspath("MailingList.json")) as f:
    mailList = json.loads(f.read())

percorso = path.dirname(path.abspath(file))
commessa = pd.read_excel(file,dtype="string", sheet_name="Matrice", usecols=["PROJECT"])
pp = pd.read_excel(file, sheet_name="Foglio1",skiprows=4, usecols=["PROJECT",'CLOSING DATE'])
pPlan = xw.Book(file)
outlook = win32.Dispatch("outlook.application")

def checkIfEmpty(pj):
    ck = pp[(pp["PROJECT"] == pj)&((pp['CLOSING DATE'].isnull())|(pp['CLOSING DATE']>= (datetime64('today')- np.timedelta64(8, 'D'))))]
    if ck.empty:
        return False
    else:
        return True

for i in range(len(commessa.index)):
    body = codecs.open("base.htm",'r')
    proj = commessa.at[i, "PROJECT"]
    if not pd.isna(proj):
        if proj in mailList:          
            pPlan.sheets[0].api.Range("A1:P15452").AutoFilter(Field:=3, Criteral:=proj)
            if checkIfEmpty(proj):
                pPlan.sheets[0].api.ExportAsFixedFormat(0,FileName:=percorso+"\\"+"".join(file.split(".")[:-1])+" - "+proj+".pdf",IgnorePrintAreas=False, OpenAfterPublish=False)
                temp = xw.Book()
                temp.sheets.add()
                pPlan.sheets['Foglio1'].range('A1:AF7000').copy(temp.sheets['Foglio1'].range('A1:AF7000'))
                temp.save(percorso+"\\"+"".join(file.split(".")[:-1])+" - "+proj+".xlsx")
                temp.close()
                mail = outlook.CreateItem(0)
                mail.To = mailList[proj]
                mail.CC = "hidden"
                mail.Subject = "".join(file.split(".")[:-1])+" - "+proj
                mail.HTMLBody = body.read()
                perk = percorso+"\\"+"".join(file.split(".")[:-1])+" - "+proj+".pdf"
                pesciolino = percorso+"\\"+"".join(file.split(".")[:-1])+" - "+proj+".xlsx"
                mail.Attachments.Add(perk)
                mail.Attachments.Add(pesciolino)
                mail.Send()

The only part where I actually have problem is the Excel copy part. It actually copies the entire sheet leaving the option to unfilter it, the rest of the code works with 0 problems.

Any solution to my problem would be nice, thanks.

EDIT: Simplier than I tought. Just added:

temp.sheets.add()
pPlan.sheets[0].used_range.api.Copy(temp.sheets[0].api.Range("A1"))
temp.save(percorso+"\\"+"".join(file.split(".")[:-1])+" - "+proj+".xlsx")
temp.close()

and removed the "old" copy part. Writing used_range instead of all range gets exactly what I wanted.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source