Exemple #1
0
def pivottable_2d(sheet: Worksheet, db: AccountDatabase,
                  vert: str, horz: str):
    ys = db.sorted_one(vert)
    xs = db.sorted_one(horz)

    for i, x in enumerate(xs):
        sheet.write(0, i+1, x, HEAD)
    sheet.write(0, i+2, '总计', HEAD)
    sheet.write(0, 0, '', HEAD)

    col_sum = [0] * len(xs)
    for i, y in enumerate(ys):
        sheet.write(i+1, 0, y, DATE)
        row_sum = 0
        for j, x in enumerate(xs):
            where = '{}={} AND {}={}'.format(vert, repr(y), horz, repr(x))
            bsum = db.select('SUM(TOTAL)', where).__next__()[0]
            sheet.write(i+1, j+1, bsum if bsum else '', TEXT)
            row_sum += bsum if bsum else 0
            col_sum[j] += bsum if bsum else 0
        sheet.write(i+1, j+2, row_sum, TEXT)

    sheet.write(i+2, 0, '总计', TEXT)
    for j, s in enumerate(col_sum):
        sheet.write(i+2, j+1, s, TEXT)
    sheet.write(i+2, j+2, sum(col_sum), TEXT)
Exemple #2
0
def pivottable_2d2(sheet: Worksheet, db: AccountDatabase,
                   vert: str, horz: str):
    ys = db.sorted_one(vert)
    xs = db.sorted_one(horz)

    for i, x in enumerate(xs):
        sheet.write_merge(0, 0, i*2+1, i*2+2, x, HEAD)
        sheet.write(1, i*2+1, '数量', HEAD)
        sheet.write(1, i*2+2, '货款', HEAD)
    sheet.write_merge(0, 1, 0, 0, '', HEAD)

    col_sum1 = [0] * len(xs)
    col_sum2 = [0] * len(xs)

    for i, y in enumerate(ys):
        sheet.write(i+2, 0, y, TEXT)
        for j, x in enumerate(xs):
            where = '{}={} AND {}={}'.format(vert, repr(y), horz, repr(x))
            sum1 = db.select('SUM(NUMBER)', where).__next__()[0]
            sheet.write(i+2, j*2+1, sum1 if sum1 else '', TEXT)
            col_sum1[j] += sum1 if sum1 else 0

            sum2 = db.select('SUM(TOTAL)', where).__next__()[0]
            sheet.write(i+2, j*2+2, sum2 if sum2 else '', TEXT)
            col_sum2[j] += sum2 if sum2 else 0

    sheet.write(i+3, 0, '总计', TEXT)
    for j, s in enumerate(col_sum1):
        sheet.write(i+3, j*2+1, s, TEXT)
    for j, s in enumerate(col_sum2):
        sheet.write(i+3, j*2+2, s, TEXT)
Exemple #3
0
def monthly(sheet: Worksheet, db: AccountDatabase):
    y = db.distinct('YEAR').__next__()[0]
    header = (['单位全名', '邮编'] + ['{}月合计'.format(i + 1)
                                for i in range(12)] + ['年合计'])
    for i, j in enumerate(header):
        sheet.write(0, i, j, BORDC)
        sheet.col(i).width_mismatch = True
        sheet.col(i).width = 3400 if i < 1 else 2100

    clients = []
    for cli in db.sales_map.values():
        clients += cli
    clients.sort()

    for i, cli in enumerate(clients, 1):
        sheet.write(i, 0, cli, BORD)
        sheet.write(i, 1, db.client_map[cli], BORDC)
        rsum = 0
        for j in range(1, 13):
            whr = 'MONTH={} AND CLIENT={} AND BASIC=1'.format(j, repr(cli))
            val = db.select('SUM(WEIGHT)', whr).__next__()[0]
            val = val / 1000 if val else 0
            sheet.write(i, j + 1, val if val else '', BORD)
            rsum += val if val else 0
        sheet.write(i, 14, rsum, BORD)
Exemple #4
0
def salesman(sheet: Worksheet, db: AccountDatabase):
    s = db.distinct('SALES').__next__()[0]
    clients = db.sorted_one('CLIENT')

    for i, j in enumerate(HEADER):
        sheet.write(0, i, j, BORDC)
        sheet.col(i).width_mismatch = True
        sheet.col(i).width = 3400 if i < 1 else 2100
    nrow = 1

    write_sales(sheet, db, s, nrow)
Exemple #5
0
def plain_text(db: AccountDatabase) -> str:
    header = '线路\t客户名称\t餐类\t货品名称\t数量\t规格\t单位'
    data = [header]
    for r in db.sorted_one('ROUTE'):
        for s in db.sorted_one('ABBR', 'ROUTE={}'.format(repr(r))):
            line = [r, s]
            tar = 'MEAL, NAME, NUMBER, SPEC, UNIT'
            whr = 'ABBR={}'.format(repr(s))
            for kind, name, num, spec, unit in db.select(tar, whr):
                nums = str(num)
                nums = nums[:-2] if nums.endswith('.0') else nums
                data.append('\t'.join(line + [kind, name, nums, spec, unit]))
    return '\n'.join(data)
Exemple #6
0
def add_route(db: AccountDatabase, route_map: RouteMap):
    # add route to database
    db.add_colume('ROUTE CHAR(32)', 'ABBR CHAR(32)')
    stm = 'UPDATE TEMP SET ROUTE=?, ABBR=? WHERE SCHOOL=?'
    for school, (route, abbr) in route_map.schools.items():
        db.cur.execute(stm, (route, abbr, school))

    # ckeck for non-routed schools
    cur = db.select('DISTINCT SCHOOL, ROUTE')
    to_del = []
    for i in cur:
        if not i[1]:
            utils.log('学校“{}”无对应路线,已丢弃其所有记录'.format(i[0]))
            to_del.append(i[0])
    for i in to_del:
        db.cur.execute('DELETE FROM TEMP WHERE SCHOOL={}'.format(repr(i)))
    db.conn.commit()

    # add order
    routes = [None] * len(route_map.rt_idx)
    for r, i in route_map.rt_idx.items():
        routes[i] = r
    db.add_order('ROUTE', routes)
    schools = [None] * len(route_map.sc_idx)
    for s, i in route_map.sc_idx.items():
        schools[i] = s
    db.add_order('SCHOOL', schools)
Exemple #7
0
def handle(manifest: Sheet, route: Sheet, does: Iterable[str] = ...):
    db = AccountDatabase(manifest)
    path = check_date_get_path(db)
    workbook = xlwt.Workbook(encoding='utf-8')

    if does is ...:
        does = ['routing', 'daily', 'printer']
    does = set(does)

    if 'routing' in does or 'printer' in does:
        route_map = RouteMap(route)
        add_route(db, route_map)

    if 'routing' in does:
        cur = db.select('DISTINCT ROUTE')
        routes = route_map.sort_route([i[0] for i in cur if i[0]])
        for route in routes:
            db.set_where('ROUTE={}'.format(repr(route)))
            distribute(workbook.add_sheet(route), db, route_map)
        db.set_where()

    if 'daily' in does:
        daily_sum(workbook.add_sheet('今日汇总'), db)

    if 'routing' in does or 'daily' in does:
        workbook.save(path)

    if 'printer' in does:
        text = plain_text(db)
        with open('标签打印表.txt', 'w', encoding='utf-8') as f:
            f.write(text)
Exemple #8
0
def pivottable_3d(sheet: Worksheet, db: AccountDatabase):
    dates = db.sorted_one('DATE')
    month = xlrd.xldate_as_tuple(dates[0], 0)[1]

    meal = db.select('DISTINCT MEAL').__next__()[0]
    school = db.select('DISTINCT SCHOOL').__next__()[0]
    title = '横县农村义务教育学生营养改善计划每日开餐情况统计 ({}月{})'
    title = title.format(month, meal)
    sheet.write_merge(0, 0, 0, len(dates)+1, title, TITLE)
    sheet.write(1, 0, '学校名称:{}'.format(school))
    sheet.write(2, 0, '明细', HEAD)

    for i, date in enumerate(dates):
        xld = xlrd.xldate_as_tuple(date, 0)[1]
        sheet.write(2, i+1, date, MONTH)
        sheet.col(i+1).width_mismatch = True
        sheet.col(i+1).width = 1500
    sheet.write(2, i+2, '总计', HEAD)

    where = 'DATE={} AND NAME={}'
    idx = 3

    sheet.write(idx, 0, '大米', SUM)
    row_sum = 0
    for i, date in enumerate(dates):
        cur = db.select('SUM(TOTAL)', where.format(date, repr('大米')))
        xs = cur.__next__()[0]
        row_sum += xs if xs else 0
        sheet.write(idx, i+1, xs if xs else '', SUM)
    sheet.write(idx, i+2, row_sum, SUM)
    idx += 1

    kinds = db.sorted_one('KIND')
    for kind in kinds:
        names = db.sorted_one('NAME', 'KIND={}'.format(repr(kind)))
        col_sum = [0] * len(dates)
        for name in names:
            row_sum = 0
            sheet.write(idx, 0, name, TEXT)
            for i, date in enumerate(dates):
                cur = db.select('SUM(TOTAL)', where.format(date, repr(name)))
                xs = cur.__next__()[0]
                row_sum += xs if xs else 0
                col_sum[i] += xs if xs else 0
                sheet.write(idx, i+1, xs if xs else '', TEXT)
            sheet.write(idx, i+2, row_sum, TEXT)
            idx += 1
        sheet.write(idx, 0, '{}合计'.format(kind), SUM)
        for i, s in enumerate(col_sum):
            sheet.write(idx, i+1, s, SUM)
        sheet.write(idx, i+2, sum(col_sum), SUM)
        idx += 1

    for i in ['每日合计', '每日开餐人数', '人均开餐金额', '陪餐人数']:
        sheet.write(idx, 0, i, TEXT)
        for j in range(1, len(dates)+2):
            sheet.write(idx, j, '', TEXT)
        idx += 1
Exemple #9
0
def handle_school(school: str, db: AccountDatabase, save_path: str):
    '''
    Save one school's data in one workbook.
    '''
    db.set_where('SCHOOL={}'.format(repr(school)))
    workbook = xlwt.Workbook(encoding='utf-8')

    pivottable_2d(workbook.add_sheet('日期'), db, 'DATE', 'MEAL')

    pivottable_2d2(workbook.add_sheet('类别'), db, 'KIND', 'MEAL')
    pivottable_2d2(workbook.add_sheet('品种'), db, 'NAME', 'MEAL')

    meals = db.sorted_one('MEAL')
    for meal in meals:
        stm = 'SCHOOL={} AND MEAL={}'
        db.set_where(stm.format(repr(school), repr(meal)))
        pivottable_3d(workbook.add_sheet('{}每日用餐'.format(meal)), db)

    workbook.save(save_path)
Exemple #10
0
def check_date_get_path(db: AccountDatabase) -> str:
    cur = db.select('DISTINCT DATE')
    dates = [i[0] for i in cur]
    if len(dates) == 0:
        raise KeyError('未发现数据或不能识别,请打开Excel文件并保存后重试')
    if len(dates) > 1:
        utils.log('建议一次只处理一天的数据,发现{}天'.format(len(dates)))
    date = xlrd.xldate_as_tuple(dates[0], 0)
    path = '分拣结果 {:02d}月{:02d}日.xls'.format(date[1], date[2])
    return path
Exemple #11
0
def handle(sheet: Sheet, log=print):
    '''
    Handle accounts of all schools in a month.
    '''
    log('读入表单数据')
    db = AccountDatabase(sheet)
    cur = db.select('DISTINCT SCHOOL')
    schools = [i[0] for i in cur if i[0]]
    cur = db.select('DISTINCT DATE')
    dates = [i[0] for i in cur if i[0]]
    months = set([xlrd.xldate_as_tuple(i, 0)[1] for i in dates])
    assert len(months) == 1, '一次只能处理一个月的数据'

    month = '{:02d}月'.format([i for i in months][0])
    path = os.path.join('.', month)
    if not os.path.exists(path):
        os.mkdir(path)
    for i, school in enumerate(schools):
        fpath = os.path.join(path, '{} {}.xls'.format(school, month))
        log('{}/{}:{}'.format(i+1, len(schools), school))
        handle_school(school, db, fpath)
Exemple #12
0
def daily_sum(sheet: Worksheet, db: AccountDatabase):
    header = ['货品类别', '货品名称', '规格', '数量']
    for i, j in enumerate(header):
        sheet.write(0, i, j, HEAD)

    kinds = db.sorted_one('KIND')
    idx = 1
    for kind in kinds:
        sheet.write(idx, 0, kind, KIND)
        cur = db.select('DISTINCT NAME, SPEC', 'KIND={}'.format(repr(kind)))
        ns = [i for i in cur]
        for name, spec in ns:
            where = 'NAME={} AND SPEC={}'.format(repr(name), repr(spec))
            num = db.select('SUM(NUMBER)', where).__next__()[0]
            sheet.write(idx, 1, name)
            sheet.write(idx, 2, spec)
            sheet.write(idx, 3, num)
            idx += 1

    sheet.set_panes_frozen(True)
    sheet.set_horz_split_pos(1)
Exemple #13
0
def annually(sheet: Worksheet, db: AccountDatabase):
    sheet.write(0, 0, '', BORD)
    header = HEADER[2:]
    for i, h in enumerate(header, 1):
        sheet.write(0, i, h, BORDC)
    for i in range(len(header) + 1):
        sheet.col(i).width_mismatch = True
        sheet.col(i).width = 2100

    ssum = [0] * len(header)
    for month in range(1, 13):
        sheet.write(month, 0, '{}月'.format(month), BORD)
        # write basic kinds
        ksum = 0
        for i, kind in enumerate(KINDS, 1):
            whr = 'MONTH={} AND KIND={}'.format(month, repr(kind))
            val = db.select('SUM(WEIGHT)', whr).__next__()[0]
            val = val / 1000 if val else 0
            ksum += val
            ssum[i - 1] += val
            sheet.write(month, i, val if val else '', BORD)
        sheet.write(month, i + 1, ksum if ksum else '', BORD)
        ssum[i] += ksum

        # write extra kinds
        for i, kind in enumerate(EXPANDS, i + 2):
            try:
                kind = '{}.0'.format(int(kind))
            except:
                pass
            whr = 'MONTH={} AND KIND={}'.format(month, repr(kind))
            val = db.select('SUM(WEIGHT)', whr).__next__()[0]
            val = val / 1000 if val else 0
            ssum[i - 1] += val
            sheet.write(month, i, val if val else '', BORD)

    # write col sum
    sheet.write(13, 0, '合计', UBORDC)
    for i, val in enumerate(ssum, 1):
        sheet.write(13, i, val)
Exemple #14
0
def write_sales(sheet: Worksheet, db: AccountDatabase, sales: str,
                nrow: int) -> int:
    ssum = [0] * (len(HEADER) - 2)
    for cli in db.sales_map[sales]:
        sheet.write(nrow, 0, cli, BORD)
        sheet.write(nrow, 1, sales, BORDC)

        # write basic kinds
        ksum = 0
        for i, kind in enumerate(KINDS, 2):
            whr = 'CLIENT={} AND KIND={}'.format(repr(cli), repr(kind))
            val = db.select('SUM(WEIGHT)', whr).__next__()[0]
            val = val / 1000 if val else 0
            ksum += val
            ssum[i - 2] += val
            sheet.write(nrow, i, val if val else '', BORD)
        sheet.write(nrow, i + 1, ksum if ksum else '', BORD)
        ssum[i - 1] += ksum

        # write extra kinds
        for i, kind in enumerate(EXPANDS, i + 2):
            try:
                kind = '{}.0'.format(int(kind))
            except:
                pass
            whr = 'CLIENT={} AND KIND={}'.format(repr(cli), repr(kind))
            val = db.select('SUM(WEIGHT)', whr).__next__()[0]
            val = val / 1000 if val else 0
            ssum[i - 2] += val
            sheet.write(nrow, i, val if val else '', BORD)
        nrow += 1

    # write sales sum
    sheet.write(nrow, 1, '合计', UBORDC)
    for i, val in enumerate(ssum, 2):
        sheet.write(nrow, i, val)
    nrow += 2
    return nrow
Exemple #15
0
def distribute(sheet: Worksheet, db: AccountDatabase, route_map: RouteMap):
    cur = db.select('DISTINCT ROUTE')
    route = cur.__next__()[0]
    sheet.write(0, 0, route, SCHOOL)
    sheet.write(0, 1, '规格', SCHOOL)

    # write goods tags in kinds' order
    kinds = db.sorted_one('KIND')
    goods = []
    for kind in kinds:
        cur = db.select('DISTINCT NAME, SPEC', 'KIND={}'.format(repr(kind)))
        goods += list(cur)
    for i, (good, spec) in enumerate(goods):
        sheet.write(i + 1, 0, good, TEXT)
        sheet.write(i + 1, 1, spec, TEXT)
    goods_sum = [0] * len(goods)

    # write schools in appearing order
    cur = db.select('DISTINCT SCHOOL')
    schools = route_map.sort_school([i[0] for i in cur])
    for i, school in enumerate(schools, 1):
        sheet.col(i + 1).width_mismatch = True
        sheet.col(i + 1).width = 2000
        sheet.write(0, i + 1, route_map.schools[school][1], SCHOOL)
        for j, (good, spec) in enumerate(goods):
            where = 'SCHOOL={} AND NAME={} AND SPEC={}'.format(
                repr(school), repr(good), repr(spec))
            cur = db.select('SUM(NUMBER)', where)
            value = cur.__next__()[0]
            goods_sum[j] += value if value else 0
            sheet.write(j + 1, i + 1, value if value else '', TEXT)

    # write goods sum
    sheet.col(i + 2).width_mismatch = True
    sheet.col(i + 2).width = 2000
    sheet.write(0, i + 2, '总计', SCHOOL)
    for j, gd in enumerate(goods_sum):
        sheet.write(j + 1, i + 2, gd, TEXT)
Exemple #16
0
def handle(manifest: Sheet, client_list: Sheet, does_sales: bool,
           does_annually: bool, does_monthly: bool):
    db = AccountDatabase(manifest, ARGS, 10)
    workbook = xlwt.Workbook(encoding='utf-8')

    db.add_order('SALES', SALESMEN)
    db.add_order('KIND', KINDS)

    # add y, m, d to table
    dates = [i[0] for i in db.distinct('DATE')]
    db.add_colume('YEAR INT', 'MONTH INT', 'DAY INT')
    for i in dates:
        t = time.strptime(i, '%Y-%m-%d')
        s = 'YEAR={}, MONTH={}, DAY={}'.format(t.tm_year, t.tm_mon, t.tm_mday)
        db.update(s, 'DATE={}'.format(repr(i)))

    years = db.sorted_one('YEAR')
    months = db.sorted_one('MONTH', 'YEAR={}'.format(years[-1]))

    # add basic_flag to table
    db.add_colume('BASIC INT')
    for i in KINDS:
        db.update('BASIC=1', 'KIND={}'.format(repr(i)))

    # add sales_map to table
    if does_sales or does_monthly:
        db.add_colume('SALES CHAR(16)')
        db.client_map = make_client_map(client_list)
        clients = [i[0] for i in db.distinct('CLIENT')]
        for cli in clients:
            sal = db.client_map.setdefault(cli, '其他')
            if sal == '其他':
                log('客户“{}”无对应业务员,归为“其他”'.format(cli))
            db.update('SALES={}'.format(repr(sal)),
                      'CLIENT={}'.format(repr(cli)))

        db.sales_map = {}
        for cli, sal in db.client_map.items():
            db.sales_map.setdefault(sal, []).append(cli)
        for clis in db.sales_map.values():
            clis.sort()

    # write salesmen
    if does_sales:
        sales = db.sorted_one('SALES')
        for s in sales:
            db.set_where('SALES={}'.format(repr(s)))
            salesman(workbook.add_sheet(s), db)

    # write anually
    if does_annually:
        for y in years:
            db.set_where('YEAR={}'.format(y))
            annually(workbook.add_sheet('{}总(料型)'.format(y)), db)

    # write monthly
    if does_monthly:
        for y in years:
            db.set_where('YEAR={}'.format(y))
            monthly(workbook.add_sheet('{}总(客户)'.format(y)), db)

    y, m = years[-1], months[-1]
    cur = db.distinct('DAY', 'YEAR={} AND MONTH={}'.format(y, m))
    d = max([i[0] for i in cur])
    path = '{:02d}.{:02d}.{:02d}-销量邮件表.xls'.format(y % 100, m, d)
    workbook.save(path)