我正在尝试重命名现有XLSX文件的标题。这个想法是使用一个excel文件将数据从XML导出到excel,并在某个用户进行调整后重新导入XML。
目前,我们已经用Excel创建了一个“模板”xlsx-sheet,其中已经包含了一个可排序表(poi中的XSSFTable)和一个到XSD-Source的映射。然后通过POI进行导入,将XML数据映射到其中并保存。为了根据用户调整工作表,我们希望将现有表的标题/列名转换为不同的语言。它与POI3.10-final一起工作,但自从升级到4.0.1后,打开时会导致损坏的XLSX文件。
我在stackoverflow上发现了这个问题,当我更改标题(列标题)中任何单元格的值时,Excel文件就会损坏,但这个问题没有得到回答,而且相当古老。但是我试图弄清楚这些注释可能是关于什么的,并试图将现有的XSSFTable扁平化,将填充的数据复制到一个新的表中,并将一个新的XSSFTable添加到数据中。可悲的是,这似乎是相当复杂的,所以我回到纠正破碎的标题单元格。我还试图用POI创建整个工作表,并逐步避免使用“模板”-XSLX,但我不知道如何实现我们的XSD-映射(在Excel中,它的开发人员-tools->source->Add,然后将节点映射到动态表中的一些单元格)
在poi升级之前工作的代码基本上是这样的:
java prettyprint-override">//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));
}
}
});
}
MyCellWalk是一个org.apache.poi.ss.util.CellWalk.CellWalk,它从左上角到右下角遍历单元格范围。
就我所知,仅仅更改单元格的平面值是不够的,因为xlsx在它们的一些映射中保留了对cellname的引用,但我无法找出如何获取所有这些引用并重命名标题。也许还有另一种方法来翻译headernames?
如果Apache POI
不会失败,xssftable.updateHeader应该可以完成这个任务。
以下所有操作都是使用Apache poi 4.0.1
完成的。
我已经下载了dummy_template.xlsx
,然后尝试更改工作表中的表列标题。但是,即使在调用xssftable.updateHeaders
之后,xssftable
中的列名也没有改变。因此,我查看了xssftable.java->updateHeaders以确定为什么没有发生这种情况。在那里我们发现:
if (row != null && row.getCTRow().validate()) {
//do changing the column names
}
<row r="4" spans="1:3" x14ac:dyDescent="0.25">
注意附加的x14ac:dydescent
属性。这就是为什么row.getctrow().validate()
返回false
。
下面的代码获取您的dummy_template.xlsx
,重命名工作表中的列标题,然后调用解除的版本Static void updateHeaders(XSSFTable表)
。之后,result.xlsx
对于在Excel
中打开有效。
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();
}
}
如果使用Excel 2007
打开dummy_template.xlsx
,然后另存为dummy_template2007.xlsx
,则该行的xml
更改为
<行r=“4”spans=“1:3”>
现在,在使用此dummy_template2007.xlsx
时,不需要手动调用xssftable.updateheaders
。由xssftable.commit
调用的xssftable.writeto自动执行此操作。
问题内容: 我以前使用Axios下载GET端点提供的文件。端点已更改,现在是POST,但是不需要参数。我正在更新原始的下载方法,但是返回了损坏的文件。 我不知道,如果问题出在,或如何响应的处理或全部的上方。到目前为止,我已经尝试了各种选择,但没有运气。任何建议将不胜感激! 我已经能够使用Postman下载文件,所以我知道端点提供的文件很好。我只是无法在我的React代码中理清参数来做到这一点。 问
我正在编写一个概念的演示证明,将电子签名添加到现有的pdf中。我遇到了一个奇怪的问题,我不明白。似乎将签名添加到某些文档可以正常工作,而将签名添加到其他文档则不行,并且会生成Adobe Reader无法打开的损坏文件。 这是我的代码: 请看这里的文件。Infile1.pdf我不能签名,但Infile2.pdf签名很好。Outfile1.pdf是损坏的文件。https://app.box.com/s
我正在使用ApachePOI,我创建了一个XSSF工作簿,并尝试打开一个xlsx文件。它在当地的一个地方很有效。但是,当我用Excel打开真正服务器(AWS EC2、Tomcat8、JDK 1.8)上的Excel文件时,它显示文件已损坏(.xls工作)。这是我的代码: 本地Spring4, jdk1.8, tomcat 8.0, maven 真正的AWS EC2亚马逊linux2,jdk1。8、t
文件重命名 文件重命名 源码/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * *//* * 程序清单:更改名称 * * 程序会创建一个操作文件的函数并导出到msh命令列表 * 在
我有一段代码,目前正在写入一个
Docx4J生成的Excel工作簿总是说损坏了,但我无法确定Excel不喜欢底层XML的什么,更不用说如何修复它了。 我的用例如下:我试图定期自动生成一个带有图表和图形的excel工作簿。只有原始数据会改变,但随着原始数据的改变,其他一切都会动态更新。 null null 在我的空白工作簿之前和之后 欢迎所有的想法。