【发布时间】:2018-03-29 14:55:20
【问题描述】:
我正在使用 JACOB 打印 Excel 文件。该文件是通过 Apache POI 创建的。当我保存文件或将其发送到 Outlook 时,一切正常,文件包含所有工作表。但是当我将文件发送到共享打印机时,它开始打印,但随后显示错误:错误 - 发送到打印机。打印作业的大小约为 230 kB,因此不应太大。
更新:当我在打印前没有更新文件时,我能够打印出文件。但是现在通过按下“打印”按钮,我必须用红色标记包含超出限制值的单元格,然后才调用打印函数。
UPDATE2:我将 Excel 文件转换为 PDF 并使用 Apache PDFBox 打印出来 - 仍然是同样的问题。 Java 中没有错误,打印了文档中的一些工作表,然后发生打印机错误:Error-Sent to printer.
UPDATE3:我添加了一个函数,用于填写 Excel 表格。
哪里出了问题?您可以在下面找到打印功能的代码:
public class AppExcelPrinter {
private ActiveXComponent excel;
private Dispatch workbooks;
private Variant workbook;
public AppExcelPrinter() { }
public synchronized void print(String filename, String printer) {
try {
ComThread.InitMTA();
excel = new ActiveXComponent("Excel.Application"); //we are going to listen to events on Application
excel.setProperty("Visible", new Variant(false)); //the file will be invisible during printing
workbooks = excel.getProperty("WorkBooks").toDispatch();
workbook = Dispatch.callN(workbooks, "Open", new Object[] { filename });
Variant From =new Variant(1);
Variant To =new Variant(6); //I have 6 sheets in my Excel file
Variant Copies =new Variant(1);
Variant Preview =new Variant(false);
Variant ActivePrinter =new Variant(printer);
Variant PrintToFile = new Variant(false);
Variant Collate = new Variant(false);
Object[] args=new Object[]{From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate};
Dispatch.call(Dispatch.get(workbook.toDispatch(), "Worksheets").toDispatch(), "PrintOut", args);
try {
Thread.sleep(100);}// the sleep is required to let everything clear out after the quit
catch (InterruptedException e) {
e.printStackTrace();}}
finally {
Variant f = new Variant(false);
Dispatch.call(workbook.toDispatch(), "Close", f);
excel.invoke("Quit", new Variant[] {});
ComThread.Release(); }}
}
填表功能:
Path original = Paths.get("");
String original1=original.toAbsolutePath().toString();
String original2=original1+"\\example.xlsx";
Path path1 = Paths.get(original2);
String target = original1+"\\temp\\temp.xlsx";
Path path2 = Paths.get(target);
try { // Copy template, which will be filled in
Files.copy(path1, path2, StandardCopyOption.REPLACE_EXISTING);}
catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error while working with temporary files", "Error", JOptionPane.ERROR_MESSAGE);}
try {
String VCAMvexp1=jTable16.getModel().getValueAt(2, 0).toString();
... //I have 6 jTables with 15 rows and 10 columns
try {
FileInputStream temp_file = new FileInputStream(new File(target));
XSSFWorkbook wb = new XSSFWorkbook(temp_file);
XSSFSheet worksheet = wb.getSheetAt(0); //separate sheet for each jTable
XSSFSheet worksheet1 = wb.getSheetAt(1);
XSSFSheet worksheet2 = wb.getSheetAt(2);
XSSFSheet worksheet3 = wb.getSheetAt(3);
XSSFSheet worksheet4 = wb.getSheetAt(4);
XSSFSheet worksheet5 = wb.getSheetAt(5);
CellStyle style = wb.createCellStyle();
style.setFillForegroundColor(IndexedColors.RED.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setBorderBottom(BorderStyle.THICK);
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderLeft(BorderStyle.THICK);
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderRight(BorderStyle.THICK);
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderTop(BorderStyle.THICK);
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
style.setAlignment(HorizontalAlignment.CENTER);
Font font = wb.createFont();
font.setFontHeightInPoints((short)10);
font.setFontName("Arial");
style.setFont(font);
Cell VCAMvexp1cell = worksheet.getRow(12).getCell(6);
VCAMvexp1cell.setCellValue(VCAMvexp1);
if (Float.parseFloat(VCAMvexp1)<Float.parseFloat(VCAMvexp1_min) || Float.parseFloat(VCAMvexp1)>Float.parseFloat(VCAMvexp1_max)) {
VCAMvexp1cell.setCellStyle(style);}
... //fill in the sheets and mark cells with red color
temp_file.close();
FileOutputStream output_file = new FileOutputStream(new File(target));
wb.write(output_file);
output_file.close();
}
catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);}
catch (IOException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);}
}
catch (NullPointerException e) {
JOptionPane.showMessageDialog(null, "Cannot save the data. Table is not filled in completely", "Error", JOptionPane.ERROR_MESSAGE);}
【问题讨论】:
-
我不确定我是否知道有一台打印机可以在发送时打印本机 Excel 工作簿!一些打印机将能够打印 PDF 或 PS,其余的需要自己的原生格式。如果在发送到打印机之前先转换为可打印格式会怎样?
-
@Gagravarr 这台打印机能够打印 Excel 工作簿。我已经使用我的应用程序打印了这个文件。但这是我刚打印出来的时候。现在我需要在打印之前在 Excel 工作簿中进行一些分析(请参阅更新)。在我用红色标记一些单元格后,我调用了我的打印功能。在这些更改之后,我得到了打印机错误。无论如何,我会检查你的建议,非常感谢!
-
@Gagravarr 我尝试使用 Apache PDFBox 打印 PDF,但仍然有这个问题 - 只打印了 5/6 张,然后“错误 - 发送到打印机”
标签: java excel apache-poi jacob