Скопировать лист с JXL на Java

Я хотел бы скопировать лист из существующего документа XLS в новый в новое место.
Как я могу сделать это с помощью JXL?

Workbook w1 = Workbook.getWorkbook(new File("ExistingDocument.xls"), settings);

WritableWorkbook w2 = Workbook.createWorkbook(new File("NewDocument.xls"));

/* So here, I would like copy the first sheet from w1 to the second sheet of w2 ... */

w2.write();
w2.close();

w1.close();

edit:
w1.getSheet(0).getCell(0, 0) не WritableCell, поэтому я не мог использовать метод copyTo.
Есть ли способ добавить ячейку / лист из w1 в w2 книгу?
edit2:
Итак, мне нужно создать копию книги с возможностью записи в другой файл?
(edit3: Или есть какая-нибудь другая бесплатная библиотека, которая может это сделать?)


Обновление:

Когда я запускаю этот код, я получаю jxl.common.AssertionFailed исключений в строке

WritableCellFormat newFormat = new WritableCellFormat(readFormat);

Если я удалю эту строку и изменю код на

newCell.setCellFormat(readFormat);

тогда стили ячеек не копируются (шрифты, границы ячеек и т. д.).

try {
    Workbook sourceDocument = Workbook.getWorkbook(new File("C:\\source.xls"));
    WritableWorkbook writableTempSource = Workbook.createWorkbook(new File("C:\\temp.xls"), sourceDocument);
    WritableWorkbook copyDocument = Workbook.createWorkbook(new File("C:\\copy.xls"));
    WritableSheet sourceSheet = writableTempSource.getSheet(0);
    WritableSheet targetSheet = copyDocument.createSheet("sheet 1", 0);

    for (int row = 0; row < sourceSheet.getRows(); row++) {
        for (int col = 0; col < sourceSheet.getColumns(); col++) {
            WritableCell readCell = sourceSheet.getWritableCell(col, row);
            WritableCell newCell = readCell.copyTo(col, row);
            CellFormat readFormat = readCell.getCellFormat();
                    /* exception on the following line */
            WritableCellFormat newFormat = new WritableCellFormat(readFormat);
            newCell.setCellFormat(newFormat);
            targetSheet.addCell(newCell);
        }
    }
    copyDocument.write();
    copyDocument.close();
    writableTempSource.close();
    sourceDocument.close();
} catch (Exception e) {
    e.printStackTrace();
}

Как я мог скопировать стили ячеек в новую ячейку?


person user    schedule 10.10.2010    source источник


Ответы (5)


Как скопировать лист из одной книги на новый лист в другой книге?

Это можно сделать, но потребуется немного поработать. Во-первых, вам нужно скопировать его ячейку (в пределах пары вложенных циклов for). Для каждой ячейки вам нужно вызвать метод copyTo(), который создаст глубокую копию. Однако формат копируется только неглубоко, поэтому вам нужно будет получить формат ячейки и использовать его конструктор копирования, а затем вызвать setCellFormat для ячейки, которую вы только что скопировали. Затем добавьте повторяющуюся ячейку в новую таблицу.

Код может выглядеть следующим образом:

 for (int i = 0 ; i < numrows ; i++){
    for (int j = 0 ; j < numcols ; j++){
        readCell = sheet.getCell(i, j);
        newCell = readCell.copyTo(i, j);
        readFormat = readCell.getCellFormat();
        newFormat = new WritableCellFormat(readFormat);
        newCell.setCellFormat(newFormat);
        newSheet.add(newCell);
    }
}

Ресурсы:

person Colin Hebert    schedule 10.10.2010
comment
Чтобы использовать метод copyTo, ячейка должна быть WritableCell. Итак, как я могу превратить Cell в WritableCell? - person user; 10.10.2010
comment
@ János Harsányi, для этого вам понадобится WritableSheet, getWritableCell() вернет WritableCell, а для этого вам понадобится WritableWorkbook - person Colin Hebert; 12.10.2010
comment
Я понимаю. Но как я мог открыть документ Excel как WritableWorkbook? А можно ли копировать из одного файла в другой? - person user; 12.10.2010
comment
@ János Harsányi, вы не можете просто открыть WritableWorkbook, вам нужно открыть Workbook с помощью getWorkbook() и создать WritableWorkbook во временном файле с помощью createWorkbook() (и вашей открытой книги в параметре). - person Colin Hebert; 12.10.2010
comment
@ János Harsányi, после редактирования вам нужно убедиться, что readFormat не null - person Colin Hebert; 13.10.2010
comment
Теперь он работает, к сожалению, не копирует диаграммы и условное форматирование (?). Есть ли способ их тоже скопировать? - person user; 13.10.2010
comment
@ János Harsányi, я думаю, что этих функций слишком много для этой библиотеки (или любой другой библиотеки XLS, о которой я знаю). - person Colin Hebert; 13.10.2010
comment
-1 Скопировать и вставить? Можно также просто предоставить ссылку и сохранить ввод. Преимущество было бы, если бы вы предоставили пример кода, который компилируется. - person demongolem; 17.09.2012

  1. Убедитесь, что readFormat не равен нулю (как указано выше)
  2. Остерегайтесь предупреждения 'Превышено максимальное количество записей формата. Использование формата по умолчанию. 'Попробуйте использовать sth, например Map<CellFormat,WritableCellFormat>, чтобы контролировать количество WritableCellFormat экземпляров.

    public static void createSheetCopy(WritableWorkbook workbook, int from, int to, String sheetName) throws WriteException {
        WritableSheet sheet = workbook.getSheet(from);
        WritableSheet newSheet = workbook.createSheet(sheetName, to);
        // Avoid warning "Maximum number of format records exceeded. Using default format."
        Map<CellFormat, WritableCellFormat> definedFormats = new HashMap<CellFormat, WritableCellFormat>();
        for (int colIdx = 0; colIdx < sheet.getColumns(); colIdx++) {
            newSheet.setColumnView(colIdx, sheet.getColumnView(colIdx));
            for (int rowIdx = 0; rowIdx < sheet.getRows(); rowIdx++) {
                if (colIdx == 0) {
                    newSheet.setRowView(rowIdx, sheet.getRowView(rowIdx));
                }
                WritableCell readCell = sheet.getWritableCell(colIdx, rowIdx);
                WritableCell newCell = readCell.copyTo(colIdx, rowIdx);
                CellFormat readFormat = readCell.getCellFormat();
                if (readFormat != null) {
                    if (!definedFormats.containsKey(readFormat)) {
                        definedFormats.put(readFormat, new WritableCellFormat(readFormat));
                    }
                    newCell.setCellFormat(definedFormats.get(readFormat));
                }
                newSheet.addCell(newCell);
            }
        }
    }
    
person Radek M    schedule 20.03.2012
comment
Ваш метод потрясающий! Я могу копировать данные ячеек и стили границ, но не объединенную область. Я потерял область слияния. Как это сделать, братан! пожалуйста, срочно помогите мне. Заранее благодарим .. Метод WorkBook.copySheet может потерять стиль границы, но не объединить область. - person Cataclysm; 14.06.2013

Просто обновление, функция «copyto» не работает с ячейкой, с каким-то измененным кодом: требуется читаемая книга, индексный номер копируемого листа, доступная для записи книга и индексный номер, в который лист должен быть скопирован, отлично работает для копирования листа из одной книги в другую.

private static WritableSheet createSheetCopy(Workbook w, int from, int to,
            WritableWorkbook writeableWorkbook) throws WriteException {
        Sheet sheet = w.getSheet(from);
        WritableSheet newSheet = writeableWorkbook.getSheet(to);
        // Avoid warning
        // "Maximum number of format records exceeded. Using default format."
        Map<CellFormat, WritableCellFormat> definedFormats = new HashMap<CellFormat, WritableCellFormat>();
        for (int colIdx = 0; colIdx < sheet.getColumns(); colIdx++) {
            newSheet.setColumnView(colIdx, sheet.getColumnView(colIdx));
            for (int rowIdx = 0; rowIdx < sheet.getRows(); rowIdx++) {
                if (colIdx == 0) {
                    newSheet.setRowView(rowIdx, sheet.getRowView(rowIdx));
                }
                Cell readCell = sheet.getCell(colIdx, rowIdx);
                Label label = new Label(colIdx, rowIdx, readCell.getContents());
                CellFormat readFormat = readCell.getCellFormat();
                if (readFormat != null) {
                    if (!definedFormats.containsKey(readFormat)) {
                        definedFormats.put(readFormat, new WritableCellFormat(
                                readFormat));
                    }
                    label.setCellFormat(definedFormats.get(readFormat));
                }
                newSheet.addCell(label);
            }
        }
        return newSheet;
    }
person Saurabh Kumar    schedule 31.07.2012

Вы должны перебирать ячейки одну за другой и добавлять их на новый лист.

См. this под вопросом Как я могу скопировать рабочий лист из одной книги на новый лист в другом рабочая тетрадь?

person Nivas    schedule 10.10.2010

JXL API wiki позволяет пользователям читать, писать, создавать и изменять листы в книге Excel (.xls) во время выполнения. Он не поддерживает формат .xlsx.

  • JXL API поддерживает документы Excel с версиями Excel 95, 97, 2000, XP, and 2003. Эти документы имеют расширение .xls

Используйте следующую функцию для копирования листа книги JXL.

public static void copySheetToWritableSheet(jxl.Sheet srcSheet, jxl.write.WritableSheet destSheet) throws JXLException {
    int numrows = srcSheet.getRows();
    int numcols = srcSheet.getColumns();
    
    System.out.println("Rows:"+numrows+", Col:"+numcols);
    for (int rowIdx = 0 ; rowIdx < numrows ; rowIdx++) {
        for (int colIdx = 0 ; colIdx < numcols ; colIdx++) {
            System.out.println("--- Rows:"+rowIdx+", Col:"+colIdx);
            jxl.Cell srcCell = srcSheet.getCell(colIdx, rowIdx);
            CellType type = srcCell.getType();
            jxl.format.CellFormat format = srcCell.getCellFormat();
            String cellValue = srcCell.getContents();
            
            WritableCellFormat cf = null;
            WritableCell newCell = null;
            
            if (format != null) {
                Colour backgroundColour = format.getBackgroundColour();
                Font font = format.getFont();
                WritableFont wf = new WritableFont(font);
                cf = new WritableCellFormat(wf);
                
                int value = backgroundColour.getValue();
                String description = backgroundColour.getDescription();
                System.out.println("Format Not Null Val:"+value+", Desc:"+description);
                if (value != 192) { // Val: 192, Desc:default background  [Dark Black]
                    cf.setBackground(backgroundColour);
                }
                
                cf.setAlignment(format.getAlignment());
                cf.setBorder(jxl.format.Border.RIGHT, format.getBorderLine(Border.RIGHT));
                cf.setBorder(Border.LEFT, format.getBorderLine(Border.LEFT));
                cf.setBorder(Border.BOTTOM, format.getBorderLine(Border.BOTTOM));
                cf.setBorder(Border.TOP, format.getBorderLine(Border.TOP));
                cf.setWrap(format.getWrap());
                
                if (type == CellType.NUMBER) {
                    newCell = new Number(colIdx, rowIdx, ((NumberCell) srcCell).getValue(), cf);
                } else {
                    newCell = new Label(colIdx, rowIdx, cellValue, cf);
                }
                CellView cellView = srcSheet.getColumnView(colIdx);
                destSheet.setColumnView(colIdx, cellView);
                destSheet.addCell(newCell);
            } else {
                WritableFont wf = new WritableFont(ARIAL_10_PT);
                // for position column we are not applying the display format
                if (type == CellType.NUMBER) {
                    cf = new WritableCellFormat(wf, displayFormat);
                    newCell = new Number(colIdx, rowIdx, ((NumberCell) srcCell).getValue(), cf);
                } else {
                    cf = new WritableCellFormat(wf);
                    newCell = new Label(colIdx, rowIdx, cellValue, cf);
                }
                CellView cellView = srcSheet.getColumnView(colIdx);
                destSheet.setColumnView(colIdx, cellView);
                destSheet.addCell(newCell); // https://stackoverflow.com/a/64675987/5081877
            }
        }
    }
    //Merge - MergedCells
    Range[] mergedCells = srcSheet.getMergedCells();
    for (int i = 0; i < mergedCells.length; i++) {
        System.out.println("mergedCells:"+i);
        Cell tl = mergedCells[i].getTopLeft();
        Cell br = mergedCells[i].getBottomRight();
        destSheet.mergeCells(tl.getColumn(), tl.getRow(), br.getColumn(), br.getRow());
    }
    
    SheetSettings srcSettings = srcSheet.getSettings();
    SheetSettings destSettings = destSheet.getSettings();
    destSettings.setZoomFactor(srcSettings.getZoomFactor());
}

Полный пример использования Java Excel API »2.6.12, Используемый образец файла - JXLWorkbook.xls.

public class JXL_XLS_Report {
    static String filePath = "C:/Yash/",
            sourceFile = filePath+"JXLWorkbook.xls", sourceFileSheetName = "FormatAbbrSheet",
            destinationFile = filePath+"JXLWorkbook_Copy.xls";
    
    public static void main(String[] args) throws Exception {
        File sourceDST = new File(destinationFile);
        jxl.write.WritableWorkbook workbook = Workbook.createWorkbook(sourceDST);
        int numberOfSheets = workbook.getNumberOfSheets();
        System.out.println("Number of Sheets:"+numberOfSheets);
        // create the empty sheet
        jxl.write.WritableSheet writableSheet = workbook.createSheet(sourceFileSheetName+"_777", numberOfSheets + 1);
        
        File source = new File(sourceFile);
        InputStream fileInStream = new FileInputStream(source);
        jxl.Workbook templateWorkbook = Workbook.getWorkbook(fileInStream, getDefaultWorkbookSettings());
        jxl.Sheet srcSheet = templateWorkbook.getSheet(sourceFileSheetName);
        
        copySheetToWritableSheet(srcSheet, writableSheet);
        
        WorkbookSettings wbSettings = new WorkbookSettings();
        wbSettings.setRationalization(false);
        
        closeWorkbook(workbook);
    }
    static jxl.biff.DisplayFormat displayFormat = new NumberFormat("0.000");
    static WritableFont ARIAL_10_PT = new WritableFont(WritableFont.ARIAL);
    //static WritableFont DataFont = new WritableFont(WritableFont.ARIAL, 8, WritableFont.BOLD);
    public static void copySheetToWritableSheet(jxl.Sheet srcSheet, jxl.write.WritableSheet destSheet) throws JXLException {
        // ...
    }
    public static void closeWorkbook(WritableWorkbook workbook) throws IOException, JXLException {
        if (workbook == null)
            return;
        if (workbook.getNumberOfSheets() == 0) {
            workbook.createSheet("No data", 0); // otherwise pointer error
        }
        //Writes out the data held in this workbook in Excel format
        workbook.write(); 
        //Close and free allocated memory 
        workbook.close(); 
    }
    public static WorkbookSettings getDefaultWorkbookSettings() {
        WorkbookSettings workbookSettings = new WorkbookSettings();
        workbookSettings.setEncoding("ISO-8859-15");
        workbookSettings.setLocale(Locale.GERMANY);
        workbookSettings.setCharacterSet(1200);
        workbookSettings.setExcelRegionalSettings("UK");
        workbookSettings.setExcelDisplayLanguage("US");
        workbookSettings.setPropertySets(false);
        return workbookSettings;
    }
    
    public static void copyCellValue(Sheet srcSheet, int srcCol, int srcRow, WritableSheet destSheet, int destCol, int destRow) throws JXLException {
        Cell srcCell = srcSheet.getCell(srcCol, srcRow);
        CellType type = srcCell.getType();
        WritableCell newCell = null;
        if (type == CellType.LABEL) {
            newCell = new Label(destCol, destRow, ((LabelCell) srcCell).getString());
        } else if (type == CellType.NUMBER) {
            newCell = new Number(destCol, destRow, ((NumberCell) srcCell).getValue());
        } else if (type == CellType.BOOLEAN) {
            newCell = new jxl.write.Boolean(destCol, destRow, ((BooleanCell) srcCell).getValue());
        } else if (type == CellType.DATE) {
            newCell = new DateTime(destCol, destRow, ((DateCell) srcCell).getDate());
        } else if (type == CellType.EMPTY) {
            newCell = new EmptyCell(destCol, destRow);
        } else if (type == CellType.NUMBER_FORMULA
                || type == CellType.STRING_FORMULA
                || type == CellType.BOOLEAN_FORMULA) {
            String formula = ((FormulaCell) srcCell).getFormula();
            newCell = new Formula(destCol, destRow, formula);
        } else {
            String cellValue = srcCell.getContents();
            newCell = new Label(destCol, destRow, cellValue);
        }
        
        // Set Column Size
        CellView cellView = srcSheet.getColumnView(srcCol);
        destSheet.setColumnView(srcCol, cellView);
        
        destSheet.addCell(newCell);
    }
    public static void copyCellFormat(Sheet srcSheet, int srcCol, int srcRow, WritableSheet destSheet, int destCol, int destRow)throws JXLException {
        CellFormat format = srcSheet.getCell(srcCol, srcRow).getCellFormat();
        if (format == null) return;
        WritableCell destCell = destSheet.getWritableCell(destCol, destRow);
        if (destCell.getType() == CellType.EMPTY) {
            WritableCell newCell = new Label(destCol, destRow, "");
            newCell.setCellFormat(format);
            destSheet.addCell(newCell);
        } else {
            destCell.setCellFormat(format);
        }
    }
}
person Yash    schedule 11.11.2020