new_col_translate.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import csv
  2. import logging
  3. from typing import List, Optional, Union
  4. from mylib.logging_config import setup_logging
  5. from mylib.pdfzh_translator import OpenAITranslator
  6. # Setup custom logging
  7. setup_logging()
  8. logger = logging.getLogger('new_col_translate')
  9. def column_letter_to_index(col_letter: str) -> int:
  10. """将Excel列字母转换为0-based索引"""
  11. index = 0
  12. for char in col_letter.upper():
  13. index = index * 26 + (ord(char) - ord('A') + 1)
  14. return index - 1
  15. def read_csv_with_header(file_path: str, encoding: str = 'cp936') -> List[List[str]]:
  16. """读取CSV文件并返回数据和表头"""
  17. try:
  18. with open(file_path, 'r', encoding=encoding) as f:
  19. reader = csv.reader(f)
  20. header = next(reader)
  21. data = [row for row in reader]
  22. logger.info(f"成功读取文件:{file_path}")
  23. logger.debug(f"表头:{header}")
  24. return header, data
  25. except Exception as e:
  26. logger.error(f"读取文件失败:{e}")
  27. raise
  28. def translate_columns_data(
  29. data: List[List[str]],
  30. header: List[str],
  31. column_indices: List[int],
  32. start_row: int = 1,
  33. end_row: Optional[int] = None,
  34. source_lang: str = 'auto',
  35. target_lang: str = 'zh-CN'
  36. ) -> List[List[str]]:
  37. """翻译多个指定列的数据"""
  38. # 记录用户传入的参数
  39. logger.info(f"翻译参数:源语言={source_lang}, 目标语言={target_lang}")
  40. logger.info(f"翻译范围:从第 {start_row} 行到第 {end_row if end_row else '最后'} 行")
  41. translator = OpenAITranslator(lang_out=target_lang, lang_in=source_lang)
  42. end_row = end_row if end_row is not None else len(data)
  43. rows_to_translate = data[start_row:end_row]
  44. logger.info(f"开始翻译 {start_row} 到 {end_row} 行的数据")
  45. # 按顺序处理每一列
  46. for i, col_index in enumerate(column_indices):
  47. # 计算当前列的实际索引(考虑之前插入的列)
  48. current_col_index = col_index + i
  49. # 插入新列
  50. for row in data:
  51. row.insert(current_col_index + 1, '')
  52. # 更新表头
  53. header.insert(current_col_index + 1, f"{header[current_col_index]}_translated")
  54. # 提取要翻译的文本
  55. texts_to_translate = [row[current_col_index] for row in rows_to_translate]
  56. # 在翻译前log出提取的内容
  57. logger.info(f"列 {current_col_index} 提取的内容示例:")
  58. for idx, text in enumerate(texts_to_translate[:3], start=start_row):
  59. logger.info(f"第 {idx} 行: {text}")
  60. # 批量翻译
  61. translated_texts = translator._batch_translate(texts_to_translate)
  62. # 将翻译结果插入新列
  63. for j, row in enumerate(rows_to_translate):
  64. row[current_col_index + 1] = translated_texts[j]
  65. logger.info(f"列 {current_col_index} 翻译完成")
  66. logger.info("所有列翻译完成")
  67. return data, header
  68. def save_csv(
  69. data: List[List[str]],
  70. header: List[str],
  71. output_file: str,
  72. encoding: str = 'utf-8-sig'
  73. ):
  74. """保存CSV文件"""
  75. try:
  76. with open(output_file, 'w', encoding=encoding, newline='') as f:
  77. writer = csv.writer(f)
  78. writer.writerow(header)
  79. writer.writerows(data)
  80. logger.info(f"结果已保存到: {output_file}")
  81. except Exception as e:
  82. logger.error(f"保存文件失败:{e}")
  83. raise
  84. def process_csv(
  85. input_file: str,
  86. output_file: str,
  87. columns: Union[str, List[str]],
  88. start_row: int = 1,
  89. end_row: Optional[int] = None,
  90. source_lang: str = 'auto',
  91. target_lang: str = 'zh-CN',
  92. encoding: str = 'cp936'
  93. ):
  94. """处理CSV文件的主函数"""
  95. try:
  96. # 记录用户传入的参数
  97. logger.info(f"处理文件:{input_file}")
  98. logger.info(f"输出文件:{output_file}")
  99. logger.info(f"处理列:{columns}")
  100. logger.info(f"编码:{encoding}")
  101. # 转换列字母为索引
  102. if isinstance(columns, str):
  103. columns = [columns]
  104. column_indices = [column_letter_to_index(col) for col in columns]
  105. # 读取文件
  106. header, data = read_csv_with_header(input_file, encoding=encoding)
  107. # 翻译指定列
  108. data, header = translate_columns_data(
  109. data,
  110. header,
  111. column_indices,
  112. start_row,
  113. end_row,
  114. source_lang,
  115. target_lang
  116. )
  117. # 保存结果
  118. save_csv(data, header, output_file)
  119. except Exception as e:
  120. logger.error(f"处理文件时出错:{e}")
  121. raise
  122. if __name__ == "__main__":
  123. from dotenv import load_dotenv
  124. load_dotenv()
  125. # 示例用法
  126. file_path = "/home/mrh/code/excel_tool/temp/测试.csv"
  127. output_path = "/home/mrh/code/excel_tool/temp/测试_processed.csv"
  128. process_csv(
  129. input_file=file_path,
  130. output_file=output_path,
  131. columns=['B', 'F', 'G', 'H'], # 现在支持多个列
  132. start_row=1,
  133. source_lang='auto',
  134. target_lang='zh-CN'
  135. )