如何在 PDF 输出的同一行显示 Excel 文件中的两个不同大小的数组?
How to display two arrays of different sizes from an Excel file displayed on same line for PDF output?
我有一个 Excel 文件,我正在使用 Apache POI 读取并获取 headers、行和单元格数据,我将其存储在两个数组中。我正在使用 PDF 框,并试图用相应的行数据垂直显示所有 header。
例如:header行包含姓名、电子邮件、出生日期、薪水和部门,后跟三行数据。每行数据都应生成自己的 PDF 文档,在页面的下方垂直列出标签和值,但现在我只想在一个 PDF 文档中列出所有值。
- 姓名:乔·史密斯
- 邮箱:js@something.com
- 出生日期:1976 年 5 月 6 日
- 工资:100,000.00 美元
- 部门:销售
我遇到的问题是 Excel sheet 中的最后一条记录正在打印到 PDF,而 header 与相应的行和单元格数据不匹配。我认为这是由于 header 数组中的 5 个元素与元胞数组中的 15 个元素的计数不匹配。
下面是我正在做的一些片段以及我的 Excel 文件布局和正在生成的 PDF 的屏幕截图。
我的 Excel Sheet(右键单击打开不知道为什么它没有链接到下面的全尺寸图片)
//Hold header values in Array
List<String> headerValues = new ArrayList<>();
//Hold cell values in Array
List<String> cellValues = new ArrayList<>();
for(int i = 0; i < headerValues.size() && i < cellValues.size(); i++){
cont.showText(headerValues.get(i) + cellValues.get(i));
cont.newLine();
}
这是我完成此操作的另一种方法,它产生与 for 循环相同的结果
Iterator<String> h = headerValues.iterator();
Iterator<String> c = cellValues.iterator();
while(h.hasNext() && c.hasNext()){
cont.showText(h.next() +":" + c.next());
cont.newLine();
}
我想要得到的结果是在我的 excel 中垂直打印每个 header 值,为我的 Excel 中的每一行数据传播sheet Sheet.
您的 collection 结构不是最佳的。至少您的单元格值不应该全部在一个列表中。默认 Excel
table 的数据结构类似于数据库 table。有由字段(列headers)组成的数据记录(行)。所以你的单元格值应该在 List<List<String>> dataRecords
中。主要 List
是行列表,内部 List
是行中的字段列表。
列 headers 可能是 List<String> colHeaders
,但更好的结构是 TreeMap<Integer, String> colHeaders
,其中 Integer
键是 [=11= 中的列索引] sheet。使用它可以清楚 sheet 中的 Excel
列真正包含数据字段。
让我们来看一个完整的例子:
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.font.*;
import org.apache.pdfbox.pdmodel.common.*;
import java.util.Map;
import java.util.TreeMap;
import java.util.List;
import java.util.ArrayList;
class GetDataFromExcel {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelExample.xlsx"));
DataFormatter dataFormatter = new DataFormatter();
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
Sheet sheet = workbook.getSheetAt(0);
int headerRowNum = sheet.getFirstRowNum();
// collecting the column headers
TreeMap<Integer, String> colHeaders = new TreeMap<Integer, String>();
Row row = sheet.getRow(headerRowNum);
for (Cell cell : row) {
int colIdx = cell.getColumnIndex();
String value = dataFormatter.formatCellValue(cell, formulaEvaluator);
colHeaders.put(colIdx, value);
}
System.out.println(colHeaders);
// collecting the data records
List<List<String>> dataRecords = new ArrayList<List<String>>();
for (int r = headerRowNum + 1; r <= sheet.getLastRowNum(); r++) {
row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
List<String> values = new ArrayList<String>();
for (Map.Entry<Integer, String> entry : colHeaders.entrySet()) {
int colIdx = entry.getKey();
Cell cell = row.getCell(colIdx); if (cell == null) cell = row.createCell(colIdx);
String value = dataFormatter.formatCellValue(cell, formulaEvaluator);
values.add(value);
}
dataRecords.add(values);
}
System.out.println(dataRecords);
workbook.close();
// create PDF
final PDFont font = PDType1Font.HELVETICA;
final float fontSize = 12.0f;
final float lineHeight = fontSize * 1.42857f;
PDPage page = new PDPage(); //U.S. Letter, 8.5" x 11"
final PDRectangle artBox = page.getArtBox();
final float artBoxHeight = artBox.getHeight();
final float artBoxWidth = artBox.getWidth();
final float leftMargin = artBoxWidth / 8.5f; // 1"
final float topMargin = artBoxHeight / 11.0f; // 1"
final float bottomMargin = artBoxHeight / 11.0f; // 1"
PDDocument doc = new PDDocument();
doc.addPage(page);
PDPageContentStream contents = new PDPageContentStream(doc, page);
contents.beginText();
contents.setFont(font, fontSize);
float currentLinePos = artBoxHeight-topMargin;
contents.newLineAtOffset(leftMargin, currentLinePos);
for (List<String> dataRecord : dataRecords) {
Integer colIdx = colHeaders.firstKey();
for (String value : dataRecord) {
if (colIdx != null) {
String header = colHeaders.get(colIdx);
if (currentLinePos <= bottomMargin) {
contents.endText();
contents.close();
page = new PDPage();
doc.addPage(page);
contents = new PDPageContentStream(doc, page);
contents.beginText();
contents.setFont(font, fontSize);
currentLinePos = artBoxHeight-topMargin;
contents.newLineAtOffset(leftMargin, currentLinePos);
}
contents.showText(header + ": " + value);
contents.newLineAtOffset(0, -lineHeight);
currentLinePos -= lineHeight;
}
colIdx = colHeaders.higherKey(colIdx);
}
contents.newLineAtOffset(0, -lineHeight);
currentLinePos -= lineHeight;
}
contents.endText();
contents.close();
doc.save("ExcelExample.pdf");
doc.close();
}
}
我有一个 Excel 文件,我正在使用 Apache POI 读取并获取 headers、行和单元格数据,我将其存储在两个数组中。我正在使用 PDF 框,并试图用相应的行数据垂直显示所有 header。
例如:header行包含姓名、电子邮件、出生日期、薪水和部门,后跟三行数据。每行数据都应生成自己的 PDF 文档,在页面的下方垂直列出标签和值,但现在我只想在一个 PDF 文档中列出所有值。
- 姓名:乔·史密斯
- 邮箱:js@something.com
- 出生日期:1976 年 5 月 6 日
- 工资:100,000.00 美元
- 部门:销售
我遇到的问题是 Excel sheet 中的最后一条记录正在打印到 PDF,而 header 与相应的行和单元格数据不匹配。我认为这是由于 header 数组中的 5 个元素与元胞数组中的 15 个元素的计数不匹配。
下面是我正在做的一些片段以及我的 Excel 文件布局和正在生成的 PDF 的屏幕截图。
我的 Excel Sheet(右键单击打开不知道为什么它没有链接到下面的全尺寸图片)
//Hold header values in Array
List<String> headerValues = new ArrayList<>();
//Hold cell values in Array
List<String> cellValues = new ArrayList<>();
for(int i = 0; i < headerValues.size() && i < cellValues.size(); i++){
cont.showText(headerValues.get(i) + cellValues.get(i));
cont.newLine();
}
这是我完成此操作的另一种方法,它产生与 for 循环相同的结果
Iterator<String> h = headerValues.iterator();
Iterator<String> c = cellValues.iterator();
while(h.hasNext() && c.hasNext()){
cont.showText(h.next() +":" + c.next());
cont.newLine();
}
我想要得到的结果是在我的 excel 中垂直打印每个 header 值,为我的 Excel 中的每一行数据传播sheet Sheet.
您的 collection 结构不是最佳的。至少您的单元格值不应该全部在一个列表中。默认 Excel
table 的数据结构类似于数据库 table。有由字段(列headers)组成的数据记录(行)。所以你的单元格值应该在 List<List<String>> dataRecords
中。主要 List
是行列表,内部 List
是行中的字段列表。
列 headers 可能是 List<String> colHeaders
,但更好的结构是 TreeMap<Integer, String> colHeaders
,其中 Integer
键是 [=11= 中的列索引] sheet。使用它可以清楚 sheet 中的 Excel
列真正包含数据字段。
让我们来看一个完整的例子:
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.font.*;
import org.apache.pdfbox.pdmodel.common.*;
import java.util.Map;
import java.util.TreeMap;
import java.util.List;
import java.util.ArrayList;
class GetDataFromExcel {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelExample.xlsx"));
DataFormatter dataFormatter = new DataFormatter();
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
Sheet sheet = workbook.getSheetAt(0);
int headerRowNum = sheet.getFirstRowNum();
// collecting the column headers
TreeMap<Integer, String> colHeaders = new TreeMap<Integer, String>();
Row row = sheet.getRow(headerRowNum);
for (Cell cell : row) {
int colIdx = cell.getColumnIndex();
String value = dataFormatter.formatCellValue(cell, formulaEvaluator);
colHeaders.put(colIdx, value);
}
System.out.println(colHeaders);
// collecting the data records
List<List<String>> dataRecords = new ArrayList<List<String>>();
for (int r = headerRowNum + 1; r <= sheet.getLastRowNum(); r++) {
row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
List<String> values = new ArrayList<String>();
for (Map.Entry<Integer, String> entry : colHeaders.entrySet()) {
int colIdx = entry.getKey();
Cell cell = row.getCell(colIdx); if (cell == null) cell = row.createCell(colIdx);
String value = dataFormatter.formatCellValue(cell, formulaEvaluator);
values.add(value);
}
dataRecords.add(values);
}
System.out.println(dataRecords);
workbook.close();
// create PDF
final PDFont font = PDType1Font.HELVETICA;
final float fontSize = 12.0f;
final float lineHeight = fontSize * 1.42857f;
PDPage page = new PDPage(); //U.S. Letter, 8.5" x 11"
final PDRectangle artBox = page.getArtBox();
final float artBoxHeight = artBox.getHeight();
final float artBoxWidth = artBox.getWidth();
final float leftMargin = artBoxWidth / 8.5f; // 1"
final float topMargin = artBoxHeight / 11.0f; // 1"
final float bottomMargin = artBoxHeight / 11.0f; // 1"
PDDocument doc = new PDDocument();
doc.addPage(page);
PDPageContentStream contents = new PDPageContentStream(doc, page);
contents.beginText();
contents.setFont(font, fontSize);
float currentLinePos = artBoxHeight-topMargin;
contents.newLineAtOffset(leftMargin, currentLinePos);
for (List<String> dataRecord : dataRecords) {
Integer colIdx = colHeaders.firstKey();
for (String value : dataRecord) {
if (colIdx != null) {
String header = colHeaders.get(colIdx);
if (currentLinePos <= bottomMargin) {
contents.endText();
contents.close();
page = new PDPage();
doc.addPage(page);
contents = new PDPageContentStream(doc, page);
contents.beginText();
contents.setFont(font, fontSize);
currentLinePos = artBoxHeight-topMargin;
contents.newLineAtOffset(leftMargin, currentLinePos);
}
contents.showText(header + ": " + value);
contents.newLineAtOffset(0, -lineHeight);
currentLinePos -= lineHeight;
}
colIdx = colHeaders.higherKey(colIdx);
}
contents.newLineAtOffset(0, -lineHeight);
currentLinePos -= lineHeight;
}
contents.endText();
contents.close();
doc.save("ExcelExample.pdf");
doc.close();
}
}