请选择 进入手机版 | 继续访问电脑版

学WPS论坛

 找回密码
 立即注册
搜索
查看: 1033|回复: 0

[Windows] EXCEL文件拆分工具

[复制链接]

105

主题

105

帖子

633

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
633
发表于 2019-10-20 01:15:28 | 显示全部楼层 |阅读模式
根据某一列,拆分成几个不同的EXCEL文件
操作方法:将EXCEL文件拖至EXE文件上,根据提示操作。

下载链接: https://pan.baidu.com/s/1ZZ6ZGDkkiTNZPIdw2ugmAQ 提取码: yfe1

工具二:
应网友要求,增加一个将EXCEL文件里的多个工作表保存为单独工作薄的小工具
下载链接: https://pan.baidu.com/s/10YDh-b2lAridY-unmSkGbg 提取码: 5dy4

EXCEL文件拆分工具使用教程.gif


来源链接:https://www.52pojie.cn/thread-1035924-1-3.html

其它Excel工具链接:
批量合并EXCEL工作表小工具 V2.3


Python源码:
  1. import openpyxl
  2. from openpyxl.utils import get_column_letter
  3. import xlrd
  4. import sys, os, collections
  5. from pprint import pprint
  6. from copy import copy


  7. class splitExcel(object):

  8.     def __init__(self, sourceFile, titleLine=None, splitColumn=None):
  9.         self.sourceFile = sourceFile
  10.         self.sourceWorkbook = openpyxl.load_workbook(sourceFile)
  11.         self.targetWorkbook = openpyxl.Workbook()
  12.         self.targetWorkbook.remove(self.targetWorkbook.active)

  13.         # 源工作表(object对象)
  14.         self.sourceWorksheet = None
  15.         # 最大行数
  16.         self.sourceWorkbookMaxRow = None
  17.         # 最大列数
  18.         self.sourceWorkbookMaxColumn = None
  19.         # 源工作表索引号
  20.         self.sourceWorksheetIndex = None
  21.         # 标题所在行号,用户输入时索引从1开始,内部处理时请留意索引数
  22.         # if titleLine == None:
  23.         #     titleLine = int(input('请输入标题所在行[2]: ').strip())
  24.         self.titleLine = titleLine
  25.         # 根据哪个列进行拆分,用户输入时索引从1开始,内部处理时请留意索引数
  26.         self.splitColumn = splitColumn
  27.         # 源工作薄当前行号
  28.         self.sbCurrectLine = None
  29.         # 目标工作薄各表当前数据行号
  30.         self.tbCurrectLines = {}
  31.         # 表头文字
  32.         self.header = []
  33.         # 各表数据
  34.         self.data = collections.OrderedDict()
  35.         # 保存列宽
  36.         self.columnsWidth = collections.OrderedDict()
  37.         # 格式
  38.         self.formats = {}

  39.     def readData(self):
  40.         wb = xlrd.open_workbook(self.sourceFile)
  41.         ws = wb.sheet_by_index(self.sourceWorksheetIndex)
  42.         for x in range(ws.nrows):
  43.             if x < self.titleLine:
  44.                 # 表头
  45.                 self.header.append(ws.row_values(x))
  46.             else:
  47.                 v = ws.cell(x, self.splitColumn - 1).value
  48.                 sheetName = self.clearSheetName(v)
  49.                 # 将表名加入data字典
  50.                 if sheetName not in self.data.keys():
  51.                     self.data[sheetName] = []
  52.                 # 添加数据
  53.                 self.data[sheetName].append(ws.row_values(x))

  54.     def selectSplitSheet(self):
  55.         if len(self.sourceWorkbook.sheetnames) == 1:
  56.             self.sourceWorksheet = self.sourceWorkbook.active
  57.             self.sourceWorksheetIndex = 0
  58.         else:
  59.             _n_ = 0
  60.             print('在工作薄中找到以下工作表:')
  61.             for SheetName in self.sourceWorkbook.sheetnames:
  62.                 print(_n_, SheetName)
  63.                 _n_ += 1

  64.             n = 0
  65.             _input = input('请输入要拆分表的序号[0]: ').strip()
  66.             if _input != '':
  67.                 n = int(_input)
  68.             self.sourceWorksheet = self.sourceWorkbook.worksheets[n]
  69.             self.sourceWorksheetIndex = n

  70.     def selectSplitColumn(self):
  71.         wb = xlrd.open_workbook(self.sourceFile)
  72.         ws = wb.sheet_by_index(self.sourceWorksheetIndex)

  73.         # 保存一下最大行数、列数,以供其它(属性)地方使用
  74.         self.sourceWorkbookMaxRow = ws.nrows
  75.         self.sourceWorkbookMaxColumn = ws.ncols

  76.         print('\n在工作表的标题行(第 %s 行)找到以下列: ' % self.titleLine)

  77.         for y in range(1, ws.ncols + 1):
  78.             print(y, ws.cell(self.titleLine - 1, y - 1).value)

  79.         columnNum = input('请输入拆分列号[2]: ').strip()
  80.         if columnNum == '':
  81.             columnNum = 2
  82.         else:
  83.             columnNum = int(columnNum)
  84.         self.splitColumn = columnNum

  85.     def readCellsStyle(self):
  86.         ws = self.sourceWorksheet
  87.         maxColumn = self.sourceWorkbookMaxColumn
  88.         styles = [[None] * (maxColumn + 11) for i in range(self.titleLine + 11)]
  89.         fonts = [[None] * (maxColumn + 11) for i in range(self.titleLine + 11)]
  90.         borders = [[None] * (maxColumn + 11) for i in range(self.titleLine + 11)]
  91.         fills = [[None] * (maxColumn + 11) for i in range(self.titleLine + 11)]
  92.         alignments = [[None] * (maxColumn + 11) for i in range(self.titleLine + 11)]
  93.         number_formats = [[None] * (maxColumn + 11) for i in range(self.titleLine + 11)]
  94.         protections = [[None] * (maxColumn + 11) for i in range(self.titleLine + 11)]
  95.         heights = [None] * (self.titleLine + 11)
  96.         widths = [None] * (maxColumn + 11)
  97.         # isDates = [None] * (maxColumn + 11)

  98.         for x in range(1, self.titleLine + 2):
  99.             heights[x] = ws.row_dimensions[x].height
  100.             # print(x,'height',heights[x])
  101.             # for y in range(1, ws.max_column + 1):
  102.             for y in range(1, maxColumn + 1):
  103.                 styles[x][y] = copy(ws.cell(x, y).style.replace('常规', 'Normal'))
  104.                 fonts[x][y] = copy(ws.cell(x, y).font)
  105.                 borders[x][y] = copy(ws.cell(x, y).border)
  106.                 fills[x][y] = copy(ws.cell(x, y).fill)
  107.                 alignments[x][y] = copy(ws.cell(x, y).alignment)
  108.                 number_formats[x][y] = copy(ws.cell(x, y).number_format)
  109.                 protections[x][y] = copy(ws.cell(x, y).protection)
  110.                 if y not in widths:
  111.                     widths[y] = ws.column_dimensions[get_column_letter(y)].width
  112.                 # print(y, get_column_letter(y), ws.column_dimensions[get_column_letter(y)].width)
  113.                 # if y not in isDates:
  114.                 #     isDates[y] = ws.cell(x, y).is_date

  115.         self.formats['heights'] = heights
  116.         self.formats['styles'] = styles
  117.         self.formats['fonts'] = fonts
  118.         self.formats['borders'] = borders
  119.         self.formats['fills'] = fills
  120.         self.formats['alignments'] = alignments
  121.         self.formats['number_formats'] = number_formats
  122.         self.formats['protections'] = protections
  123.         self.formats['widths'] = widths
  124.         # self.formats['isDates'] = isDates

  125.     def writeFormatToNewWorkbook(self):
  126.         for sheetName in self.data.keys():
  127.             ws = self.targetWorkbook[sheetName]
  128.             # for x in range(1,self.titleLine+2):
  129.             for x in range(1, ws.max_row + 1):
  130.                 # 表头
  131.                 if x <= self.titleLine:
  132.                     xx = x
  133.                     # ws.row_dimensions[x].height = self.formats['heights'][x]
  134.                 else:
  135.                     # 表数据
  136.                     xx = self.titleLine + 1
  137.                 height = self.formats['heights'][xx]
  138.                 if not height == None and height > 0:
  139.                     ws.row_dimensions[x].height = self.formats['heights'][xx]

  140.                 for y in range(1, ws.max_column + 1):
  141.                     # 表头
  142.                     if x <= self.titleLine:
  143.                         # 路过空白单元格
  144.                         # if ws.cell(x, y).value == '':
  145.                         #     continue
  146.                         width = self.formats['widths'][y]
  147.                         if not width == None and width > 0:
  148.                             ws.column_dimensions[get_column_letter(y)].width = self.formats['widths'][y]
  149.                         xx = x
  150.                     else:
  151.                         # 表数据
  152.                         xx = self.titleLine + 1
  153.                     ws.cell(x, y).style = self.formats['styles'][xx][y]
  154.                     ws.cell(x, y).font = self.formats['fonts'][xx][y]
  155.                     ws.cell(x, y).border = self.formats['borders'][xx][y]
  156.                     ws.cell(x, y).fill = self.formats['fills'][xx][y]
  157.                     ws.cell(x, y).alignment = self.formats['alignments'][xx][y]
  158.                     ws.cell(x, y).number_format = self.formats['number_formats'][xx][y]
  159.                     ws.cell(x, y).protection = self.formats['protections'][xx][y]

  160.                     # if x>self.titleLine and self.formats['isDates'][y]:
  161.                     #     ws.cell(x, y).number_format = 'yyyy/mm/dd'

  162.     def writeDataToNewWorkbook(self):
  163.         for sheetName in self.data.keys():
  164.             ws = self.targetWorkbook.create_sheet(sheetName)
  165.             # 写入头文字
  166.             x = 0  # 行号
  167.             for row in self.header:
  168.                 x += 1
  169.                 y = 0  # 列号
  170.                 for cellValue in row:
  171.                     y += 1
  172.                     if not cellValue == '':
  173.                         ws.cell(x, y).value = cellValue
  174.             # 写入数据
  175.             for row in self.data[sheetName]:
  176.                 ws.append(row)

  177.     def clearSheetName(self, name, replaceAs='-'):
  178.         invalidChars = r':\/?*[]:'
  179.         for c in invalidChars:
  180.             name = name.replace(c, replaceAs).strip()
  181.         return name

  182.     def selectTitleLine(self):
  183.         wb = xlrd.open_workbook(self.sourceFile)
  184.         ws = wb.sheet_by_index(self.sourceWorksheetIndex)

  185.         # 保存一下最大行数、列数,以供其它(属性)地方使用
  186.         self.sourceWorkbookMaxRow = ws.nrows
  187.         self.sourceWorkbookMaxColumn = ws.ncols

  188.         print('打印所拆分工作表前10行,前5列数据:')
  189.         maxY = ws.ncols
  190.         if ws.ncols > 5:
  191.             maxY = 5
  192.         for x in range(10):
  193.             tempList = []
  194.             for y in range(maxY):
  195.                 tempList.append(ws.cell(x, y).value)
  196.             print('第%s行:' % (x + 1), tempList)

  197.         titleLine = 2
  198.         n = input('\n请输入标题行所在行号[2]:').strip()
  199.         if not n == '':
  200.             titleLine = int(n)

  201.         self.titleLine = titleLine

  202.     def make(self):
  203.         self.selectSplitSheet()
  204.         self.selectTitleLine()
  205.         self.selectSplitColumn()

  206.         print('开始读取数据...')
  207.         self.readData()
  208.         print('开始读取格式...')
  209.         self.readCellsStyle()
  210.         print('开始写入数据至分表...')
  211.         self.writeDataToNewWorkbook()
  212.         print('开始写入格式至分表...')
  213.         self.writeFormatToNewWorkbook()

  214.     def save(self, filename=None):
  215.         if filename == None:
  216.             splitPath = os.path.split(self.sourceFile)
  217.             filename = splitPath[0] + '/拆分_' + splitPath[1]
  218.         self.targetWorkbook.save(filename)
  219.         self.sourceWorkbook.close()
  220.         self.targetWorkbook.close()
  221.         return filename


  222. class saveWorksheetToWorkbook(object):
  223.     def __init__(self, excelFile):
  224.         self.excelFile = excelFile

  225.     def saveTo(self, savePath=None, addNumToFilename=True):
  226.         if savePath == None:
  227.             splitPath = os.path.splitext(self.excelFile)
  228.             savePath = splitPath[0]
  229.             if not os.path.exists(savePath):
  230.                 os.makedirs(savePath, exist_ok=True)

  231.         wb = openpyxl.load_workbook(self.excelFile)
  232.         sheetNames = wb.sheetnames
  233.         wb.close()

  234.         #
  235.         # _input=input('正在保存各表至独立工作薄,文件名前是否加序号?[Y] Y/N:').strip().lower()
  236.         # if _input=='n':
  237.         #     addNumToFilename=False

  238.         n=0
  239.         for sheetName in sheetNames:
  240.             n+=1
  241.             print('保存', n, sheetName)
  242.             wb = openpyxl.load_workbook(self.excelFile)
  243.             for ws in wb.worksheets:
  244.                 if not sheetName == ws.title:
  245.                     wb.remove(ws)

  246.             xh=''
  247.             if addNumToFilename:
  248.                 xh=str(n)
  249.             filename='%s/%s%s.xlsx' % (savePath, xh,sheetName)
  250.             wb.save(filename)
  251.             wb.close()

  252.         return savePath


  253. if __name__ == '__main__':
  254.     file = r'C:\Users\Eyes\Desktop\汇总.xlsx'
  255.     file = sys.argv[1]
  256.     se = splitExcel(file)
  257.     # file = r'C:\Users\Eyes\Desktop\2019年积分排名-2019-07-09.xlsx'
  258.     # se = splitExcel(file, 1, 3)
  259.     se.make()
  260.     f = se.save()
  261.     print('拆分汇总文件:', f)

  262.     # f=r'C:\Users\Eyes\Desktop\汇总.拆分.xlsx'
  263.     saveTo = saveWorksheetToWorkbook(f)
  264.     p = saveTo.saveTo()
  265.     print('拆分表保存文件夹:', p)

  266.     input('\n完成,按回车键退出。')
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|学WPS BBS. ( 豫ICP备13020861号-11 ) 网站运行了

GMT+8, 2022-12-5 03:02 , Processed in 0.077665 second(s), 35 queries .

Powered by Discuz! X3.4 Designed by BBs.xuewps.Com

© 2019- Comsenz Inc. www.xuewps.com

快速回复 返回顶部 返回列表