字段顺序,金蝶导出

This commit is contained in:
李鹏宇
2026-02-13 22:25:05 +08:00
parent ace17caad1
commit 67eeb51cd4
4 changed files with 138 additions and 3 deletions
@@ -3,6 +3,8 @@ import xlwt
import base64
import io
from openpyxl import load_workbook
from openpyxl.styles import Alignment
from copy import copy
from odoo.modules import get_module_resource
from datetime import datetime, timedelta, date
@@ -286,3 +288,128 @@ class PropertyAccountsReceivable(models.Model):
'url': f'/web/content/{attachment.id}?download=true',
'target': 'self',
}
def export_kingdee_receivable(self):
"""导出应收单金蝶数据到Excel模板"""
# 获取勾选的应收账单记录
receivable_ids = self._context.get('active_ids', [])
if not receivable_ids:
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'message': '请先勾选需要导出的应收账单记录',
'type': 'warning',
'sticky': False,
}
}
receivable_records = self.env['property.accounts.receivable'].browse(receivable_ids)
# 加载模板文件
template_path = get_module_resource('yuthon_property', 'static', 'tmpl', 'yingshoudanjindiedaoru.xlsx')
workbook = load_workbook(template_path)
sheet = workbook.active
# 从第3行开始写入数据(第1-2行是表头)
row = 3
# 序号起始值
sequence_number = 104101
# 获取模板样式行(使用第3行作为参考,但会被数据覆盖)
# 建议:确保模板第3行有完整的样式设置
template_row_idx = 3
if sheet.max_row >= template_row_idx:
# 先保存第3行的样式
template_styles = {}
for col in range(1, 37): # A到AJ列(36列)
cell = sheet.cell(row=template_row_idx, column=col)
template_styles[col] = {
'font': copy(cell.font),
'fill': copy(cell.fill),
'border': copy(cell.border),
'alignment': copy(cell.alignment),
}
else:
template_styles = {}
for record in receivable_records:
# 先解除当前行的合并单元格(如果有)
merged_cells_to_unmerge = []
for merged_range in sheet.merged_cells.ranges:
if merged_range.min_row <= row <= merged_range.max_row:
merged_cells_to_unmerge.append(str(merged_range))
for merged_range_str in merged_cells_to_unmerge:
sheet.unmerge_cells(merged_range_str)
# 先为所有列应用模板样式
for col in range(1, 37): # A到AJ列
cell = sheet.cell(row=row, column=col)
if col in template_styles:
cell.font = copy(template_styles[col]['font'])
cell.fill = copy(template_styles[col]['fill'])
cell.border = copy(template_styles[col]['border'])
cell.alignment = copy(template_styles[col]['alignment'])
# A列:序号(从104101开始)
sheet.cell(row=row, column=1, value=sequence_number)
# B列:应收开始日期
if record.due_date:
sheet.cell(row=row, column=2, value=record.due_date.strftime('%Y-%m-%d'))
# C列:应收结束日期
if record.due_date_end:
sheet.cell(row=row, column=3, value=record.due_date_end.strftime('%Y-%m-%d'))
# E列:物业地址(设置自动换行)
e_cell = sheet.cell(row=row, column=5, value=record.property_name or '')
e_cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)
# M列:租赁单位(第13列)
rent_company = ''
if record.contract_id:
rent_company = record.contract_id.rent_company or ''
sheet.cell(row=row, column=13, value=rent_company)
# N列:备注(设置自动换行)
n_cell = sheet.cell(row=row, column=14, value=record.remark or '')
n_cell.alignment = Alignment(horizontal='left', vertical='center', wrap_text=True)
# 设置行高为自动(让Excel自动调整)
# 为确保自动换行生效,设置最小行高
if not sheet.row_dimensions[row].height or sheet.row_dimensions[row].height < 30:
sheet.row_dimensions[row].height = 30 # 设置最小行高30,确保能显示2-3行文本
# P列:承租方
sheet.cell(row=row, column=16, value=record.lessee_id.name if record.lessee_id else '')
# AF列:税率(第32列)
sheet.cell(row=row, column=32, value=record.tax or 0)
# AJ列:当期金额(第36列)
sheet.cell(row=row, column=36, value=record.original_amount or 0)
row += 1
sequence_number += 1
# 保存到内存
output = io.BytesIO()
workbook.save(output)
output.seek(0)
excel_data = base64.b64encode(output.read())
output.close()
# 创建附件并返回下载
attachment = self.env['ir.attachment'].create({
'name': '应收单金蝶导入.xlsx',
'datas': excel_data,
'mimetype': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'type': 'binary',
})
return {
'type': 'ir.actions.act_url',
'url': f'/web/content/{attachment.id}?download=true',
'target': 'self',
}
@@ -162,4 +162,12 @@
<field name="state">code</field>
<field name="code">action = model.export_batch_invoice()</field>
</record>
<record id="export_kingdee_receivable_action" model="ir.actions.server">
<field name="name">应收单金蝶导出</field>
<field name="model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="binding_model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">action = model.export_kingdee_receivable()</field>
</record>
</odoo>
@@ -36,9 +36,6 @@
<field name="liquidation_salary_staff" string="2024年清算工资(职工)"/>
<field name="business_special_bonus" string="2025经营特别奖"/>
<field name="business_base" string="2025年基础年终奖"/>
<field name="one_year_sum" string="一次性年终奖应发合计"/>
<field name="one_year_tax" string="一次性年终奖计税"/>
<field name="one_year_tax" string="一次性年终奖实发"/>
<!-- 扣发类字段 -->
<field name="deduct_performance_bonus" string="扣发绩效奖金"/>
@@ -71,6 +68,9 @@
<field name="trade_union_dues" string="工会会费"/>
<field name="actual_paid_salary" string="实发工资" decoration-danger="1" decoration-bf="1"/>
<field name="meal_allowance" string="误餐费"/>
<field name="one_year_sum" string="一次性年终奖应发合计"/>
<field name="one_year_tax" string="一次性年终奖计税"/>
<field name="one_year_tax" string="一次性年终奖实发"/>
<field name="reimbursed_medical_exam_fee" string="已报销体检费"/>
<field name="remaining_medical_exam_fee" string="剩余体检费"/>