cdc.office.tools.KeyedTableDiffExporter Maven / Gradle / Ivy
The newest version!
package cdc.office.tools;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Workbook;
import org.odftoolkit.odfdom.doc.OdfSpreadsheetDocument;
import org.odftoolkit.odfdom.dom.style.OdfStyleFamily;
import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeStyles;
import org.odftoolkit.odfdom.incubator.doc.style.OdfStyle;
import cdc.office.ss.WorkbookKind;
import cdc.office.ss.WorkbookWriter;
import cdc.office.ss.WorkbookWriterFeatures;
import cdc.office.ss.WorkbookWriterHelper;
import cdc.office.ss.csv.CsvWorkbookWriter;
import cdc.office.ss.excel.ExcelWorkbookWriter;
import cdc.office.ss.odf.OdsWorkbookWriter;
import cdc.office.tables.Header;
import cdc.office.tables.TableSection;
import cdc.office.tables.diff.CellDiff;
import cdc.office.tables.diff.CellDiffKind;
import cdc.office.tables.diff.KeyedTableDiff;
import cdc.office.tables.diff.KeyedTableDiff.Synthesis.Action;
import cdc.office.tables.diff.LocalizedCellDiff;
import cdc.office.tables.diff.RowDiff;
import cdc.office.tables.diff.RowDiffKind;
import cdc.office.tables.diff.Side;
import cdc.tuples.CTupleN;
import cdc.tuples.TupleN;
import cdc.util.encoding.ExtensionEncoder;
import cdc.util.lang.Checks;
import cdc.util.lang.UnexpectedValueException;
import cdc.util.strings.StringComparison;
/**
* Class used to export a KeyedTableDiff to an Office file.
*
* @author Damien Carbonne
*/
public final class KeyedTableDiffExporter {
public static final String DEFAULT_ADDED_MARK = "";
public static final String DEFAULT_REMOVED_MARK = "";
public static final String DEFAULT_CHANGED_MARK = "";
public static final String DEFAULT_UNCHANGED_MARK = "";
public static final String DEFAULT_FILE1_MARK = "1";
public static final String DEFAULT_FILE2_MARK = "2";
public static final String DEFAULT_DIFF_MARK = "Diff";
public static final String DEFAULT_DIFF_SHEET_NAME = "Delta";
public static final String DEFAULT_SYNTHESIS_SHEET_NAME = "Synthesis";
private String file1Mark;
private String file2Mark;
private String diffMark;
private String changedMark;
private String addedMark;
private String removedMark;
private String unchangedMark;
private String diffSheetName = DEFAULT_DIFF_SHEET_NAME;
private String synthesisSheetName;
private WorkbookWriterFeatures features;
private int maxRowsPerSheet;
private Header header1;
private Header header2;
private final ExtensionEncoder encoder1 = new ExtensionEncoder<>(String.class, String.class);
private final ExtensionEncoder encoder2 = new ExtensionEncoder<>(String.class, String.class);
private final Set hints = EnumSet.noneOf(Hint.class);
public enum Hint {
/** If set, one column describing the change of each line is added. */
ADD_LINE_DIFF_COLUMN,
/** If set, one column describing the change of each cell is added for each data column. */
ADD_CELL_DIFF_COLUMNS,
/** If set, the synthesis sheet is generated. */
SAVE_SYNTHESIS,
/** If set, in each changed cell, both values are displayed. */
SHOW_CHANGE_DETAILS,
/** If set, colors are used with formats that supports them. */
SHOW_COLORS,
/** If set, lines are sorted using key columns. */
SORT_LINES,
/** If set, text marks are used to show changes. */
SHOW_MARKS,
/** If set, original ,names are displayed in headers. Useful when mapping is used. */
SHOW_ORIGINAL_NAMES,
/** If set, lines that are identical are displayed. */
SHOW_UNCHANGED_LINES,
/** If set, 2 columns are displayed for each input column: one first data 1, one for data 2 */
SPLIT_COMPARISONS,
/** If set, indexing is disabled. Should be used when one knows that result holds on 1 sheet. */
NO_INDEXING
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter() {
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setHeader1(Header header1) {
this.header1 = header1;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setHeader2(Header header2) {
this.header2 = header2;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setMap1(Map map1) {
for (final Map.Entry entry : map1.entrySet()) {
this.encoder1.put(entry.getKey(), entry.getValue());
}
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setMap2(Map map2) {
for (final Map.Entry entry : map2.entrySet()) {
this.encoder2.put(entry.getKey(), entry.getValue());
}
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setFile1Mark(String file1Mark) {
this.file1Mark = file1Mark;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setFile2Mark(String file2Mark) {
this.file2Mark = file2Mark;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setDiffMark(String diffMark) {
this.diffMark = diffMark;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setChangedMark(String changedMark) {
this.changedMark = changedMark;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setAddedMark(String addedMark) {
this.addedMark = addedMark;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setRemovedMark(String removedMark) {
this.removedMark = removedMark;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setUnchangedMark(String unchangedMark) {
this.unchangedMark = unchangedMark;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setFeatures(WorkbookWriterFeatures features) {
this.features = WorkbookWriterFeatures.builder()
.set(features)
.enable(WorkbookWriterFeatures.Feature.NO_CELL_STYLES)
.build();
return this;
}
private KeyedTableDiffExporter hint(Hint hint,
boolean enabled) {
if (enabled) {
hints.add(hint);
} else {
hints.remove(hint);
}
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setSortLines(boolean sortLines) {
return hint(Hint.SORT_LINES, sortLines);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setShowUnchangedLines(boolean showUnchangedLines) {
return hint(Hint.SHOW_UNCHANGED_LINES, showUnchangedLines);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setShowColors(boolean showColors) {
return hint(Hint.SHOW_COLORS, showColors);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setShowMarks(boolean showMarks) {
return hint(Hint.SHOW_MARKS, showMarks);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setShowChangeDetails(boolean showChangeDetails) {
return hint(Hint.SHOW_CHANGE_DETAILS, showChangeDetails);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setSheetName(String sheetName) {
this.diffSheetName = sheetName;
return this;
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setSaveSynthesis(boolean saveSynthesis) {
return hint(Hint.SAVE_SYNTHESIS, saveSynthesis);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setAddLineDiffColumn(boolean addLineDiffColumn) {
return hint(Hint.ADD_LINE_DIFF_COLUMN, addLineDiffColumn);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setAddCellDiffColumns(boolean addCellDiffColumns) {
return hint(Hint.ADD_CELL_DIFF_COLUMNS, addCellDiffColumns);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setShowOriginalNames(boolean showOriginalNames) {
return hint(Hint.SHOW_ORIGINAL_NAMES, showOriginalNames);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setSplitComparisons(boolean splitComparisons) {
return hint(Hint.SPLIT_COMPARISONS, splitComparisons);
}
@Deprecated(since = "2024-06-02", forRemoval = true)
public KeyedTableDiffExporter setMaxRowsPerSheet(int maxRowsPerSheet) {
this.maxRowsPerSheet = maxRowsPerSheet;
return this;
}
private KeyedTableDiffExporter(Builder builder) {
this.file1Mark = Checks.isNotNull(builder.file1Mark, "file1Mark");
this.file2Mark = Checks.isNotNull(builder.file2Mark, "file2Mark");
this.diffMark = Checks.isNotNull(builder.diffMark, "diffMark");
this.changedMark = Checks.isNotNull(builder.changedMark, "changeMark");
this.addedMark = Checks.isNotNull(builder.addedMark, "addedMark");
this.removedMark = Checks.isNotNull(builder.removedMark, "removedMark");
this.unchangedMark = Checks.isNotNull(builder.unchangedMark, "unchangedMark");
this.diffSheetName = Checks.isNotNull(builder.diffSheetName, "diffSheetName");
this.synthesisSheetName = Checks.isNotNull(builder.synthesisSheetName, "synthesisSheetName");
this.features = WorkbookWriterFeatures.builder()
.set(builder.features)
.enable(WorkbookWriterFeatures.Feature.NO_CELL_STYLES)
.build();
this.maxRowsPerSheet = builder.maxRowsPerSheet;
this.header1 = Checks.isNotNull(builder.header1, "header1");
this.header2 = Checks.isNotNull(builder.header2, "header2");
this.hints.addAll(builder.hints);
for (final Map.Entry entry : builder.map1.entrySet()) {
this.encoder1.put(entry.getKey(), entry.getValue());
}
for (final Map.Entry entry : builder.map2.entrySet()) {
this.encoder2.put(entry.getKey(), entry.getValue());
}
}
private String getOriginalName(String name,
Side side) {
if (side == Side.LEFT) {
final String s = encoder1.decode(name);
if (s == null) {
if (header1.contains(name)) {
return name;
} else {
return "?";
}
} else {
return s;
}
} else {
final String s = encoder2.decode(name);
if (s == null) {
if (header2.contains(name)) {
return name;
} else {
return "?";
}
} else {
return s;
}
}
}
public void save(KeyedTableDiff diff,
File file) throws IOException {
final WorkbookKind outputKind = WorkbookKind.from(file);
if (outputKind == null) {
throw new IOException("Unrecognized output format for " + file);
}
switch (outputKind) {
case CSV -> new CsvGenerator().generate(file, diff);
case XLS, XLSX, XLSM -> new ExcelGenerator().generate(file, diff);
case ODS -> new OdsGenerator().generate(file, diff);
default -> throw new UnexpectedValueException(outputKind);
}
}
/**
* Adds a synthesis sheet to a workbook.
*
* @param synthesis The synthesis.
* @param writer The writer.
* @throws IOException When an IO error occurs.
*/
public void addSynthesisSheet(KeyedTableDiff.Synthesis synthesis,
WorkbookWriter> writer) throws IOException {
final boolean hasDuplicates = synthesis.getLinesCount(Action.DUPLICATE1) > 0
|| synthesis.getLinesCount(Action.DUPLICATE2) > 0;
final String NA = "N/A";
writer.beginSheet(synthesisSheetName);
writer.beginRow(TableSection.HEADER);
writer.addCells("Item",
Action.ADDED,
Action.REMOVED,
Action.CHANGED,
Action.SAME);
if (hasDuplicates) {
writer.addCells(
Action.DUPLICATE1,
Action.DUPLICATE2);
}
writer.beginRow(TableSection.DATA);
writer.addCell("Lines");
writer.addCell(synthesis.getLinesCount(Action.ADDED));
writer.addCell(synthesis.getLinesCount(Action.REMOVED));
writer.addCell(synthesis.getLinesCount(Action.CHANGED));
writer.addCell(synthesis.getLinesCount(Action.SAME));
if (hasDuplicates) {
writer.addCell(synthesis.getLinesCount(Action.DUPLICATE1));
writer.addCell(synthesis.getLinesCount(Action.DUPLICATE2));
}
writer.beginRow(TableSection.DATA);
writer.addCell("Cells");
writer.addCell(synthesis.getCellsCount(Action.ADDED));
writer.addCell(synthesis.getCellsCount(Action.REMOVED));
writer.addCell(synthesis.getCellsCount(Action.CHANGED));
writer.addCell(synthesis.getCellsCount(Action.SAME));
if (hasDuplicates) {
writer.addCell(NA);
writer.addCell(NA);
}
for (final String name : synthesis.getColumnNames()) {
writer.beginRow(TableSection.DATA);
if (hints.contains(Hint.SHOW_ORIGINAL_NAMES)) {
writer.addCell(name + " (" + getOriginalName(name, Side.LEFT) + "/" + getOriginalName(name, Side.RIGHT) + ")");
} else {
writer.addCell(name);
}
writer.addCell(synthesis.getColumnCellsCount(name, Action.ADDED));
writer.addCell(synthesis.getColumnCellsCount(name, Action.REMOVED));
writer.addCell(synthesis.getColumnCellsCount(name, Action.CHANGED));
writer.addCell(synthesis.getColumnCellsCount(name, Action.SAME));
if (hasDuplicates) {
writer.addCell(NA);
writer.addCell(NA);
}
}
}
/**
* Adds diff sheets to a workbook.
*
* @param diff The differences
* @param writer The writer.
* @throws IOException When an IO error occurs.
*/
public void addDiffSheets(KeyedTableDiff diff,
WorkbookWriter> writer) throws IOException {
if (writer instanceof final CsvWorkbookWriter w) {
new CsvGenerator().generate(w, diff);
} else if (writer instanceof final ExcelWorkbookWriter w) {
new ExcelGenerator().generate(w, diff);
} else if (writer instanceof final OdsWorkbookWriter w) {
new OdsGenerator().generate(w, diff);
} else {
throw new IllegalArgumentException("Unsupported writer " + writer);
}
}
/**
* Base generator class.
*
* @author Damien Carbonne
*
* @param The WorkbookWriter type.
*/
private abstract class AbstractGenerator> {
private String wrap(String s) {
return s == null ? "" : s;
}
private String getEffectiveMark(CellDiffKind kind) {
if (hints.contains(Hint.SHOW_MARKS)) {
switch (kind) {
case ADDED:
return addedMark;
case CHANGED:
return changedMark;
case REMOVED:
return removedMark;
case NULL, SAME:
return unchangedMark;
default:
throw new UnexpectedValueException(kind);
}
} else {
return "";
}
}
private void generateHeader(W writer,
Header header) throws IOException {
// Header
writer.beginRow(TableSection.HEADER);
// Add the line diff column
if (hints.contains(Hint.ADD_LINE_DIFF_COLUMN)) {
addHeaderCell(writer, wrap(diffMark));
}
// Add other columns
for (final String name : header.getSortedNames()) {
if (hints.contains(Hint.ADD_CELL_DIFF_COLUMNS)) {
addHeaderCell(writer, name + " " + diffMark);
}
if (hints.contains(Hint.SPLIT_COMPARISONS)) {
if (hints.contains(Hint.SHOW_ORIGINAL_NAMES)) {
addHeaderCell(writer, name + " " + file1Mark + " " + getOriginalName(name, Side.LEFT));
addHeaderCell(writer, name + " " + file2Mark + " " + getOriginalName(name, Side.RIGHT));
} else {
addHeaderCell(writer, name + " " + file1Mark);
addHeaderCell(writer, name + " " + file2Mark);
}
} else {
if (hints.contains(Hint.SHOW_ORIGINAL_NAMES)) {
addHeaderCell(writer,
name + " " + getOriginalName(name, Side.LEFT) + " " + getOriginalName(name, Side.RIGHT));
} else {
addHeaderCell(writer, name);
}
}
}
}
protected final void generate(W writer,
KeyedTableDiff diff) throws IOException {
initWorkbook(writer);
final WorkbookWriterHelper helper = new WorkbookWriterHelper<>(writer, !hints.contains(Hint.NO_INDEXING));
if (hints.contains(Hint.SAVE_SYNTHESIS)) {
addSynthesisSheet(diff.getSynthesis(), writer);
}
// Initial diff header
// It does not take into account options that can add new columns
final Header header = diff.getDiffHeader();
if (hints.contains(Hint.NO_INDEXING)) {
helper.beginSheets(diffSheetName, "", w -> generateHeader(w, header), maxRowsPerSheet);
} else {
helper.beginSheets(diffSheetName + "#", "", w -> generateHeader(w, header), maxRowsPerSheet);
}
// Data
final List> keys = diff.getKeys();
if (hints.contains(Hint.SORT_LINES)) {
final Comparator> comparator = TupleN.comparator(StringComparison::compareDecimalDigits);
Collections.sort(keys, comparator);
}
for (final CTupleN key : keys) {
final RowDiff rdiff = diff.getDiff(key);
if (rdiff.getKind() != RowDiffKind.SAME || hints.contains(Hint.SHOW_UNCHANGED_LINES)) {
helper.beginRow(TableSection.DATA);
if (hints.contains(Hint.ADD_LINE_DIFF_COLUMN)) {
addMarkCell(writer, rdiff.getKind());
}
for (final LocalizedCellDiff lcdiff : rdiff.getDiffs()) {
final CellDiff cdiff = lcdiff.getDiff();
if (hints.contains(Hint.ADD_CELL_DIFF_COLUMNS)) {
addMarkCell(writer, cdiff.getKind());
}
switch (cdiff.getKind()) {
case ADDED:
if (hints.contains(Hint.SPLIT_COMPARISONS)) {
addEmptyCell(writer);
}
addSingleValueCell(writer,
cdiff.getKind(),
getEffectiveMark(cdiff.getKind()) + wrap(cdiff.getRight()));
break;
case SAME, NULL:
if (hints.contains(Hint.SPLIT_COMPARISONS)) {
addSingleValueCell(writer,
cdiff.getKind(),
getEffectiveMark(cdiff.getKind()) + wrap(cdiff.getLeft()));
}
addSingleValueCell(writer,
cdiff.getKind(),
getEffectiveMark(cdiff.getKind()) + wrap(cdiff.getRight()));
break;
case CHANGED:
if (hints.contains(Hint.SPLIT_COMPARISONS)) {
addSingleValueCell(writer,
CellDiffKind.REMOVED,
getEffectiveMark(CellDiffKind.REMOVED) + wrap(cdiff.getLeft()));
addSingleValueCell(writer,
CellDiffKind.ADDED,
getEffectiveMark(CellDiffKind.ADDED) + wrap(cdiff.getRight()));
} else {
if (hints.contains(Hint.SHOW_CHANGE_DETAILS)) {
addDualValueCell(writer,
getEffectiveMark(CellDiffKind.REMOVED) + wrap(cdiff.getLeft()),
getEffectiveMark(CellDiffKind.ADDED) + wrap(cdiff.getRight()));
} else {
addSingleValueCell(writer,
CellDiffKind.CHANGED,
getEffectiveMark(CellDiffKind.CHANGED) + wrap(cdiff.getRight()));
}
}
break;
case REMOVED:
addSingleValueCell(writer,
cdiff.getKind(),
getEffectiveMark(cdiff.getKind()) + wrap(cdiff.getLeft()));
if (hints.contains(Hint.SPLIT_COMPARISONS)) {
addEmptyCell(writer);
}
break;
default:
throw new UnexpectedValueException(cdiff.getKind());
}
}
}
}
}
protected final void generate(File file,
KeyedTableDiff diff) throws IOException {
try (final W writer = createWorkbook(file)) {
generate(writer, diff);
}
}
protected abstract W createWorkbook(File file) throws IOException;
protected abstract void initWorkbook(W writer) throws IOException;
protected abstract void addHeaderCell(W writer,
String name) throws IOException;
protected abstract void addMarkCell(W writer,
RowDiffKind kind) throws IOException;
protected abstract void addMarkCell(W writer,
CellDiffKind kind) throws IOException;
protected abstract void addEmptyCell(W writer) throws IOException;
protected abstract void addSingleValueCell(W writer,
CellDiffKind kind,
String value) throws IOException;
protected abstract void addDualValueCell(W writer,
String value1,
String value2) throws IOException;
}
/**
* Csv Generator.
*
* @author Damien Carbonne
*/
private final class CsvGenerator extends AbstractGenerator {
public CsvGenerator() {
super();
}
@Override
protected CsvWorkbookWriter createWorkbook(File file) throws IOException {
return new CsvWorkbookWriter(file, features);
}
@Override
protected void initWorkbook(CsvWorkbookWriter writer) throws IOException {
// Ignore
}
@Override
protected void addHeaderCell(CsvWorkbookWriter writer,
String name) throws IOException {
writer.addCell(name);
}
@Override
protected void addMarkCell(CsvWorkbookWriter writer,
RowDiffKind kind) throws IOException {
writer.addCell(kind);
}
@Override
protected void addMarkCell(CsvWorkbookWriter writer,
CellDiffKind kind) throws IOException {
writer.addCell(kind);
}
@Override
protected void addEmptyCell(CsvWorkbookWriter writer) throws IOException {
writer.addEmptyCell();
}
@Override
protected void addSingleValueCell(CsvWorkbookWriter writer,
CellDiffKind kind,
String value) throws IOException {
writer.addCell(value);
}
@Override
protected void addDualValueCell(CsvWorkbookWriter writer,
String value1,
String value2) throws IOException {
writer.addCell(value1 + "\n" + value2);
}
}
/**
* Excel Generator.
*
* @author Damien Carbonne
*/
private final class ExcelGenerator extends AbstractGenerator {
private CellStyle addedStyle;
private CellStyle removedStyle;
private CellStyle changedStyle;
private CellStyle unchangedStyle;
private CellStyle headerStyle;
private Font removedFont;
private Font addedFont;
public ExcelGenerator() {
super();
}
private void createStyles(Workbook workbook) {
if (hints.contains(Hint.SHOW_COLORS)) {
addedStyle = createStyle(workbook, IndexedColors.BLUE);
removedStyle = createStyle(workbook, IndexedColors.RED);
changedStyle = createStyle(workbook, IndexedColors.PINK);
unchangedStyle = createStyle(workbook, IndexedColors.BLACK);
removedFont = createFont(workbook, IndexedColors.RED);
addedFont = createFont(workbook, IndexedColors.BLUE);
} else {
addedStyle = null;
removedStyle = null;
changedStyle = null;
unchangedStyle = null;
removedFont = null;
addedFont = null;
}
headerStyle = createStyle(workbook, IndexedColors.BLACK);
}
private CellStyle getStyle(CellDiffKind kind) {
switch (kind) {
case ADDED:
return addedStyle;
case CHANGED:
return changedStyle;
case REMOVED:
return removedStyle;
case SAME, NULL:
return unchangedStyle;
default:
throw new UnexpectedValueException(kind);
}
}
private CellStyle getStyle(RowDiffKind kind) {
switch (kind) {
case ADDED:
return addedStyle;
case CHANGED:
return changedStyle;
case REMOVED:
return removedStyle;
case SAME:
return unchangedStyle;
default:
throw new UnexpectedValueException(kind);
}
}
@Override
protected ExcelWorkbookWriter createWorkbook(File file) throws IOException {
return new ExcelWorkbookWriter(file,
features,
true);
}
@Override
protected void initWorkbook(ExcelWorkbookWriter writer) throws IOException {
createStyles(writer.getWorkbook());
}
@Override
protected void addHeaderCell(ExcelWorkbookWriter writer,
String name) throws IOException {
writer.addCell(name);
if (hints.contains(Hint.SHOW_COLORS)) {
writer.getCell().setCellStyle(headerStyle);
}
}
@Override
protected void addMarkCell(ExcelWorkbookWriter writer,
RowDiffKind kind) throws IOException {
writer.addCell(kind);
if (hints.contains(Hint.SHOW_COLORS)) {
writer.getCell().setCellStyle(getStyle(kind));
}
}
@Override
protected void addMarkCell(ExcelWorkbookWriter writer,
CellDiffKind kind) throws IOException {
writer.addCell(kind);
if (hints.contains(Hint.SHOW_COLORS)) {
writer.getCell().setCellStyle(getStyle(kind));
}
}
@Override
protected void addEmptyCell(ExcelWorkbookWriter writer) throws IOException {
writer.addEmptyCell();
}
@Override
protected void addSingleValueCell(ExcelWorkbookWriter writer,
CellDiffKind kind,
String value) throws IOException {
writer.addCell(value);
if (hints.contains(Hint.SHOW_COLORS)) {
writer.getCell().setCellStyle(getStyle(kind));
}
}
@Override
protected void addDualValueCell(ExcelWorkbookWriter writer,
String value1,
String value2) throws IOException {
if (hints.contains(Hint.SHOW_COLORS)) {
// Set default style to removed and set font for added.
// Otherwise, it seems some issues may arise with large files.
final int leftLength = value1.length();
final String s = value1 + "\n" + value2;
final RichTextString text = writer.getWorkbook().getCreationHelper().createRichTextString(s);
// text.applyFont(0, leftLength, removedFont);
text.applyFont(leftLength, s.length(), addedFont);
writer.addCell("");
writer.getCell().setCellStyle(removedStyle);
writer.getCell().setCellValue(text);
} else {
writer.addCell(value1 + "\n" + value2);
}
}
}
/**
* Ods Generator.
*
* @author Damien Carbonne
*/
private final class OdsGenerator extends AbstractGenerator {
public OdsGenerator() {
super();
}
private void createStyle(OdfSpreadsheetDocument doc) {
final OdfOfficeStyles styles = doc.getOrCreateDocumentStyles();
final OdfStyle style = styles.newStyle("xxx", OdfStyleFamily.Text);
}
@Override
protected OdsWorkbookWriter createWorkbook(File file) throws IOException {
return new OdsWorkbookWriter(file, features);
}
@Override
protected void initWorkbook(OdsWorkbookWriter writer) throws IOException {
// TODO init
}
@Override
protected void addHeaderCell(OdsWorkbookWriter writer,
String name) throws IOException {
writer.addCell(name);
// TODO style
}
@Override
protected void addMarkCell(OdsWorkbookWriter writer,
RowDiffKind kind) throws IOException {
writer.addCell(kind);
// TODO style
}
@Override
protected void addMarkCell(OdsWorkbookWriter writer,
CellDiffKind kind) throws IOException {
writer.addCell(kind);
// TODO style
}
@Override
protected void addEmptyCell(OdsWorkbookWriter writer) throws IOException {
writer.addEmptyCell();
}
@Override
protected void addSingleValueCell(OdsWorkbookWriter writer,
CellDiffKind kind,
String value) throws IOException {
writer.addCell(value);
// TODO style
}
@Override
protected void addDualValueCell(OdsWorkbookWriter writer,
String value1,
String value2) throws IOException {
writer.addCell(value1 + "\n" + value2);
// TODO style
}
}
static CellStyle createStyle(Workbook workbook,
IndexedColors color) {
// Try to retrieve a previously created style
// for (int index = 0; index < workbook.getNumCellStyles(); index++) {
// final CellStyle s = workbook.getCellStyleAt(index);
// final int i = s.getFontIndex();
// final Font f = workbook.getFontAt(i);
// if (f.getColor() == color.index) {
// return s;
// }
// }
final CellStyle style = workbook.createCellStyle();
// style.setWrapText(true);
final Font font = workbook.createFont();
font.setColor(color.index);
style.setFont(font);
return style;
}
static Font createFont(Workbook workbook,
IndexedColors color) {
final Font font = workbook.createFont();
font.setColor(color.index);
return font;
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private String file1Mark = DEFAULT_FILE1_MARK;
private String file2Mark = DEFAULT_FILE2_MARK;
private String diffMark = DEFAULT_DIFF_MARK;
private String changedMark = DEFAULT_CHANGED_MARK;
private String addedMark = DEFAULT_ADDED_MARK;
private String removedMark = DEFAULT_REMOVED_MARK;
private String unchangedMark = DEFAULT_UNCHANGED_MARK;
private String diffSheetName = DEFAULT_DIFF_SHEET_NAME;
private String synthesisSheetName = DEFAULT_SYNTHESIS_SHEET_NAME;
private int maxRowsPerSheet = -1;
private Header header1;
private Header header2;
private WorkbookWriterFeatures features = WorkbookWriterFeatures.STANDARD_FAST;
private final Map map1 = new HashMap<>();
private final Map map2 = new HashMap<>();
private final Set hints = EnumSet.noneOf(Hint.class);
private Builder() {
}
public Builder file1Mark(String file1Mark) {
this.file1Mark = file1Mark;
return this;
}
public Builder file2Mark(String file2Mark) {
this.file2Mark = file2Mark;
return this;
}
public Builder diffMark(String diffMark) {
this.diffMark = diffMark;
return this;
}
public Builder changedMark(String changedMark) {
this.changedMark = changedMark;
return this;
}
public Builder addedMark(String addedMark) {
this.addedMark = addedMark;
return this;
}
public Builder removedMark(String removedMark) {
this.removedMark = removedMark;
return this;
}
public Builder unchangedMark(String unchangedMark) {
this.unchangedMark = unchangedMark;
return this;
}
public Builder diffSheetName(String diffSheetName) {
this.diffSheetName = diffSheetName;
return this;
}
public Builder synthesisSheetName(String synthesisSheetName) {
this.synthesisSheetName = synthesisSheetName;
return this;
}
public Builder maxRowsPerSheet(int maxRowsPerSheet) {
this.maxRowsPerSheet = maxRowsPerSheet;
return this;
}
public Builder header1(Header header1) {
this.header1 = header1;
return this;
}
public Builder header2(Header header2) {
this.header2 = header2;
return this;
}
public Builder features(WorkbookWriterFeatures features) {
this.features = features;
return this;
}
public Builder map1(Map map1) {
this.map1.putAll(map1);
return this;
}
public Builder map2(Map map2) {
this.map2.putAll(map2);
return this;
}
public Builder hint(Hint hint) {
this.hints.add(hint);
return this;
}
public Builder hint(Hint hint,
boolean enabled) {
if (enabled) {
this.hints.add(hint);
} else {
this.hints.remove(hint);
}
return this;
}
public KeyedTableDiffExporter build() {
return new KeyedTableDiffExporter(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy