亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

重命名 XSSF 表的頭與阿帕奇 Poi 導致損壞的 XLSX 文件

重命名 XSSF 表的頭與阿帕奇 Poi 導致損壞的 XLSX 文件

HUX布斯 2022-09-22 19:47:20
我正在嘗試重命名現有 xlsx 文件的標頭。這個想法是有一個excel文件將數據從XML導出到excel,并在一些用戶進行調整后重新導入XML。目前,我們已經創建了一個帶有Excel的“模板”xlsx工作表,其中已經包含一個可排序的表格(poi中的XSSFTable)和一個到XSD源的映射。然后我們通過POI導入它,將XML數據映射到其中并保存它。為了根據用戶調整工作表,我們希望將此現有表的標題/列名翻譯成不同的語言。它與POI 3.10-FINAL一起使用,但自從升級到4.0.1以來,它會導致打開時xlsx文件損壞。我發現這個問題堆棧溢出已經 Excel文件被損壞,當我改變標題(列標題)中任何單元格的值,但它沒有得到回答和相當舊。但是我試圖弄清楚注釋可能是什么,并試圖平展現有的XSSFTable,將填充的數據復制到新工作表中,然后將新的XSSFTable放在數據上。可悲的是,這似乎非常復雜,所以我又回到了糾正破碎的標題單元格。我還嘗試使用POI創建整個工作表,并避免使用該“模板”-xslx,但我無法弄清楚如何實現我們的XSD映射(在Excel中,其開發人員工具->源->添加,然后將節點映射到動態表中的某些單元格)在poi升級之前工作的代碼基本上是這樣的://Sheet is the current XSSFSheet//header is a Map with the original header-name from the template mapped to a the new translated name//headerrownumber is the row containing the tableheader to be translated public static void translateHeaders(Sheet sheet,final Map<String,String> header,int headerrownumber) {  CellRangeAddress address = new CellRangeAddress(headerrownumber,headerrownumber,0,sheet.getRow(headerrownumber).getLastCellNum());  //Cellrange is the header-row        MyCellWalk cellWalk = new MyCellWalk (sheet,address);        cellWalk.traverse(new CellHandler() {            public void onCell(Cell cell, CellWalkContext ctx) {                String val = cell.getStringCellValue();                if (header.containsKey(val)) {                    cell.setCellValue(header.get(val));                }            }        });}“我的細胞之路”是一個組織,它遍歷從左上角到右下角的單元格范圍。據我所知,僅僅更改單元格的平面值是不夠的,因為xlsx在一些映射中保留了對單元格名稱的引用,但是我無法弄清楚如何全部獲取它們并重命名標題。也許還有另一種方法來翻譯標題名稱?
查看完整描述

1 回答

?
繁花不似錦

TA貢獻1851條經驗 獲得超4個贊

好吧,XSSFTable.更新標題應該可以做到這一點,如果這樣做不會失敗的話。apache poi

以下所有操作都是使用 完成的。apache poi 4.0.1

我已經下載了你的,然后嘗試更改工作表中的表格列標題。但即使調用了列名之后,在 中也沒有改變。因此,我查看了 XSSFTable.java -> 更新標題以確定為什么不會發生這種情況。在那里,我們發現:dummy_template.xlsxXSSFTable.updateHeadersXSSFTable

if (row != null && row.getCTRow().validate()) {

 //do changing the column names

}

因此,僅當工作表中的相應行根據名稱空格有效時,才會更改列名稱。但在后來的版本中(2007年之后),增加了額外的命名空間。在本例中,該行如下所示:XMLOffice Open XMLExcelXML


<row r="4" spans="1:3" x14ac:dyDescent="0.25">

請注意附加屬性。這就是返回的原因。x14ac:dyDescentrow.getCTRow().validate()false


以下代碼獲取您的 ,重命名工作表中的列標題,然后調用解除版本。之后,在 中打開 有效。dummy_template.xlsxstatic void updateHeaders(XSSFTable table)result.xlsxExcel


import org.apache.poi.ss.usermodel.*;

import org.apache.poi.ss.util.*;

import org.apache.poi.ss.util.cellwalk.*;


import org.apache.poi.xssf.usermodel.*;


import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;


import java.io.*;

import java.util.*;


class ExcelRenameTableColumns {


 static void translateHeaders(Sheet sheet, final Map<String,String> header, int headerrownumber) {

  CellRangeAddress address = new CellRangeAddress(

   headerrownumber, headerrownumber, 

   0, sheet.getRow(headerrownumber).getLastCellNum());


  CellWalk cellWalk = new CellWalk (sheet, address);

  cellWalk.traverse(new CellHandler() {

   public void onCell(Cell cell, CellWalkContext ctx) {

    String val = cell.getStringCellValue();

    if (header.containsKey(val)) {

     cell.setCellValue(header.get(val));

    }

   }

  });

 }


 static void updateHeaders(XSSFTable table) {

  XSSFSheet sheet = (XSSFSheet)table.getParent();

  CellReference ref = table.getStartCellReference();


  if (ref == null) return;


  int headerRow = ref.getRow();

  int firstHeaderColumn = ref.getCol();

  XSSFRow row = sheet.getRow(headerRow);

  DataFormatter formatter = new DataFormatter();


System.out.println(row.getCTRow().validate()); // false!


  if (row != null /*&& row.getCTRow().validate()*/) {

   int cellnum = firstHeaderColumn;

   CTTableColumns ctTableColumns = table.getCTTable().getTableColumns();

   if(ctTableColumns != null) {

    for (CTTableColumn col : ctTableColumns.getTableColumnList()) {

     XSSFCell cell = row.getCell(cellnum);

     if (cell != null) {

      col.setName(formatter.formatCellValue(cell));

     }

     cellnum++;

    }

   }

  }

 }


 public static void main(String[] args) throws Exception {


  String templatePath = "dummy_template.xlsx";

  String outputPath = "result.xlsx";


  FileInputStream inputStream = new FileInputStream(templatePath);

  Workbook workbook = WorkbookFactory.create(inputStream);

  Sheet sheet = workbook.getSheetAt(0);


  Map<String, String> header = new HashMap<String, String>();

  header.put("textone", "Spalte eins");

  header.put("texttwo", "Spalte zwei");

  header.put("textthree", "Spalte drei");


  translateHeaders(sheet, header, 3);


  XSSFTable table = ((XSSFSheet)sheet).getTables().get(0);


  updateHeaders(table);


  FileOutputStream outputStream = new FileOutputStream(outputPath);

  workbook.write(outputStream);

  outputStream.close();

  workbook.close();


 }

}

如果我打開使用,然后另存為 ,則該行的更改更改為dummy_template.xlsxExcel 2007dummy_template2007.xlsxXML


<row r="4" spans="1:3">


現在,在使用它時,無需手動調用。由 調用的 XSSFTable.write To 會自動執行此操作。dummy_template2007.xlsxXSSFTable.updateHeadersXSSFTable.commit


查看完整回答
反對 回復 2022-09-22
  • 1 回答
  • 0 關注
  • 178 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號