"Ich möchte Excel in Java ausgeben, aber ich möchte es nicht durch eine Zellennummer wie Apache POI angeben", "Ich möchte eine Bibliothek auf etwas höherer Ebene", ich habe eine Bibliothek namens XlsMapper gefunden, also habe ich es versucht Es war. Bitte weisen Sie auf Fehler oder Implementierungshinweise hin.
Eine Java-Bibliothek, die Excel Java zuordnet. Früher gab es eine berühmte Java-Bibliothek namens XLSBeans, die zu einem Buch verarbeitet wurde, aber ihre Entwicklung scheint gestoppt zu sein. Basierend auf dieser Version 1.1 scheinen Einzelpersonen nach und nach Funktionen als weiteres Projekt XlsMapper hinzuzufügen. (Eigentlich habe ich eine Weile XLS Beans verwendet.)
Wenn Sie über POI auf Excel zugreifen, wird für die Liste aus der Datenbank (wenn Sie die Informationen kennen) Aufzeichnung 1. Setzen und formatieren Sie Element 1 in der Zelle in der M-ten Spalte des N-ten Datensatzes in Excel. Aufzeichnung 1. Setzen und formatieren Sie Element 2 auf die Zelle in der Spalte M + 1. des N-ten Excel-Datensatzes. : Aufzeichnung 2. Setzen und formatieren Sie Element 1 in der Zelle in der M-ten Spalte von N + 1. Datensatz in Excel. :
Wenn Sie einen solchen Zugriff implementieren müssen oder wenn sich die Spaltenstruktur ändert, müssen Sie die N- und M-Werte entsprechend verschieben. Mit dieser Bibliothek können Sie Excel-Werte POJOs zuordnen und die zugeordneten POJOs wie einem OR-Mapper in Excel schreiben, wodurch unnötige Verarbeitungsbeschreibungen reduziert werden. Darüber hinaus müssen Sie sich nicht die Mühe machen, das Format usw. zu implementieren, da Einstellungen wie das Kopieren des vorherigen Datensatzes mit Anmerkungen vorgenommen werden können.
Maven Fügen Sie pom Folgendes hinzu. * Ausgelassen, außer für Excel-bezogene Elemente.
pom.xml
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.github.mygreen</groupId>
<artifactId>xlsmapper</artifactId>
<version>2.0</version>
</dependency>
Bereiten Sie ein Buch mit der folgenden Tabelle vor. Es geht darum, die Tabelle mit einer Linie zu versehen.
SpringBootApplication
DemoService.java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
//Geben Sie das Argument einfach als Map zurück
CommandLineParamsMap params = new CommandLineParamsMap(args);
try (ConfigurableApplicationContext ctx = SpringApplication.run(DemoApplication.class, args)) {
DemoService app = ctx.getBean(DemoService.class);
app.execute(params);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Service
DemoService.java
@Service
@Slf4j
public class DemoService {
private static final String TEMPLATE_FILE_PATH = "template\\Benutzerliste_%s Jahr%s Monat%s Tagesschöpfung.xlsx";
private static final String OUTPUT_FILE_PATH = "C:\\test\\Benutzerliste_%s Jahr%s Monat%s Tagesschöpfung.xlsx";
public String execute(CommandLineParamsMap params) {
log.info("DemoService START");
LocalDate outPutDate = getOutPutDate(params.getValue("date"));
log.info("date:" + outPutDate);
String outputPath = makeTargetPath(outPutDate);
//Tabellendaten abrufen
List<UsingListRecord> target = getData();
//Stellen Sie jede Information in Blatt ein
UsingListSheet sheet = new UsingListSheet();
sheet.setOutPutDate("Ausgabedatum:" + outPutDate);
sheet.setRecords(target);
//Fügen Sie der letzten Zeile die gesamte Zeile der Formel hinzu
sheet.addSummaryRecord();
XlsMapper xlsMapper = new XlsMapper();
try {
//Schreiben Sie dies (keine Schleife erforderlich)!
xlsMapper.save(
new FileInputStream(TEMPLATE_FILE_PATH), //Excel-Datei der Vorlage
new FileOutputStream(outputPath), //Excel-Datei zum Schreiben
sheet //Daten erstellt
);
} catch (XlsMapperException | IOException e) {
throw new RuntimeException(e);
}
//Lesen Sie die geschriebene Tabelle und versuchen Sie, sie auszugeben
List<UsingListRecord> records = read(outputPath);
records.forEach(r->log.info(r.toString()));
log.info("DemoService END");
return "###########success###########";
}
/**
*yyyymmdd → LocalDate-Objekt
* @param value
* @return
*/
private LocalDate getOutPutDate(String value) {
int year = Integer.parseInt(value.substring(0, 4));
int month = Integer.parseInt(value.substring(4, 6));
int day = Integer.parseInt(value.substring(6, 8));
return LocalDate.of(year, month, day);
}
//Datenerfassung
private List<UsingListRecord> getData() {
//Eigentlich bringen Sie es aus der DB
List<UsingListRecord> list = new ArrayList<>();
list.add(getSample("Anakin Skywalker", "Tatween", "Mensch", 100, "Asoka Tano", 1));
list.add(getSample("Padme Amidara", "Naboo", "Mensch", 100, null, 2));
list.add(getSample("Luke Skywalker", "Polizei Masa", "Mensch", 100, "Kairo Ren", 3));
list.add(getSample("Kairo Ren", "Chandrila", "Mensch", 100, null, 4));
list.add(getSample("Asoka Tano", "Siri", "Togruta", 100, null, 5));
list.add(getSample("Darth Mall", "Dasomia", "Zabrak", null, "Wilde Opres", 6));
list.add(getSample("Yoda", null, "Yodaの種族", 800, "Luke Skywalker", 7));
return list;
}
//Gibt einen geeigneten Beispieldatensatz zurück
private UsingListRecord getSample(String name, String homeTown, String species, Integer ageAvg, String apprentice,
int i) {
LocalDate d1 = LocalDate.of(2019, 3, 1).plusDays(i);
Date startDate = Date.from(d1.atStartOfDay(ZoneId.systemDefault()).toInstant());
UsingListRecord record = new UsingListRecord();
record.setUserName(name);
record.setPrice(new BigDecimal(120000 + i));
record.setTax(0.08d + i);
record.setUsingStartDate(startDate);
record.setHomeTown(homeTown);
record.setSpecies(species);
record.setAgeAvg(ageAvg);
record.setApprentice(apprentice);
return record;
}
private List<UsingListRecord> read(String targetPath) {
XlsMapper xlsMapper = new XlsMapper();
UsingListSheet sheet = null;
try {
sheet = xlsMapper.load(
new FileInputStream(targetPath), //Excel-Datei zu lesen
UsingListSheet.class //Kommentierte Klasse.
);
} catch (XlsMapperException | IOException e) {
throw new RuntimeException(e);
}
return sheet.getRecords();
}
private String makeTargetPath(LocalDate batchDate) {
return String.format(OUTPUT_FILE_PATH,
batchDate.getYear(),
batchDate.getMonthValue(),
batchDate.getDayOfMonth()
);
}
}
Sheet Eine Klasse, die ein Blatt darstellt. Geben Sie @XlsSheet (name = "sheet name") an.
UsingListSheet.java
@Slf4j
@Data
@XlsSheet(name = "Benutzerliste")
public class UsingListSheet {
private String outPutDate;
@XlsHorizontalRecords(tableLabel = "Benutzerliste", bottom = 3)
@XlsRecordOption(overOperation = OverOperation.Copy)
private List<UsingListRecord> records;
public void addSummaryRecord() {
if (records == null) {
this.records = new ArrayList<>();
}
UsingListRecord record = new UsingListRecord();
//Übergeben Sie Ihre eigene Instanz
record.setParent(this);
record.setUserName("gesamt");
records.add(record);
}
/**
*Versuchen Sie nach dem Schreiben der Tabelle, das Ausgabedatum mit POI festzulegen.
* @param sheet
*/
@XlsPostSave
public void aa(final Sheet sheet) {
Cell cell = POIUtils.getCell(sheet, 7, 0);
CellStyle style=cell.getCellStyle();
cell.setCellValue(outPutDate);
cell.setCellStyle(style);
}
}
@XlsHorizontalRecords Stellen Sie einen Tabellentyp mit einer Überschrift oben ein, z. B. das unten angehängte Excel. Geben Sie den Titel der Tabelle mit tableLabel an. Der untere Bereich gibt an, wie weit die tatsächliche Tabelle vom tableLabel entfernt ist. Wenn sich direkt unter tableLabel eine Tabellenüberschrift befindet, muss diese nicht angegeben werden.
@XlsRecordOption(overOperation = OverOperation.Copy) Geben Sie an, was zu tun ist, wenn mehr Datenzeilen vorhanden sind als in der Vorlage angegeben (durch den Rand festgelegt). Im Fall von OverOperation.Copy wird das Format der Zeile eine Ebene darüber kopiert und eine Zeile hinzugefügt. OverOperation.Insert beschädigt die Arbeitsmappe. (Siehe die Umgebung, die ich oben aus dem Grund ausprobiert habe.)
@XlsPostSave Die Methode dazu wird nach dem Schreiben der Datei automatisch ausgeführt. Es kann auch der Methode der Record-Klasse zugewiesen werden. Die Reihenfolge lautet @XlsPostSave of Sheet → @XlsPostSave of Record. Es gibt viele andere Dinge wie @XlsPreSave, siehe unten. 7. Verwalten von Lebenszyklusereignissen
Record Eine Klasse, die einen Datensatz der Tabelle darstellt, die in der Excel-Tabelle platziert werden soll.
UsingListRecord.java
@Data
public class UsingListRecord {
//Zugeordnete Standortinformationen
private Map<String, CellPosition> positions;
//Übergeordnete Bean-Informationen
private UsingListSheet parent;
@XlsColumn(columnName = "Nutzer")
private String userName;
@XlsColumn(columnName = "Gebühr")
@XlsFormula(methodName = "getSumFormula", primary = false)
private BigDecimal price;
@XlsColumn(columnName = "Umsatzsteuersatz")
private Double tax;
@XlsColumn(columnName = "Startdatum der Nutzung")
@XlsDateTimeConverter(excelPattern = "yyyy/m/d")
private Date usingStartDate;
@XlsColumn(columnName = "Geburtsort")
@XlsDefaultValue(value="--", cases=ProcessCase.Save)
private String homeTown;
@XlsColumn(columnName = "Rennen")
private String species;
@XlsColumn(columnName = "Durchschnittliches Leben")
private Integer ageAvg;
@XlsColumn(columnName = "Schüler")
@XlsDefaultValue(value="--", cases=ProcessCase.Save)
private String apprentice;
//Stellen Sie die Gesamtformel zusammen
public String getSumFormula(Point point) {
//Ausgabeformel nur, wenn die Heimatstadt insgesamt ist
if (!userName.equals("gesamt")) {
return null;
}
//Datensatzgröße (Wert, der in der Datensatzzeile nach Summen sucht)
final int dataSize = parent.getRecords().size() - 1;
//Spaltenname
final String colAlpha = CellReference.convertNumToColString(point.x);
//Beginn des Gesamtwertes/Endzeilennummer
final int startRowNumber = point.y - dataSize + 1;
final int endRowNumber = point.y;
return String.format("SUM(%s%d:%s%d)", colAlpha, startRowNumber, colAlpha, endRowNumber);
}
}
@XlsFormula Wenn Sie im entsprechenden Feld einen Wert angeben, wird durch die Angabe von primary = false Priorität vergeben. Wenn true, hat die Formel immer Vorrang.
@XlsDefaultValue Setzen Sie den Standardwert für NULL mit value. Wenn case = ProcessCase.Save angegeben ist, wird der Standardwert nur zum Schreiben festgelegt.
Geben Sie "date = 20190312" als Argument in die Ausführungskonfiguration der Springboot-App ein, wenden Sie sie an und führen Sie sie aus.
Wenn Sie sich das Formelfenster ansehen, wird die Formel auch ordnungsgemäß ausgegeben.
Protokollieren Sie beim Lesen der Tabelle nach dem Schreiben. Die Erfassung erfolgt ordnungsgemäß.
Protokoll (Auszug)
com.example.demo.service.DemoService : date:2019-03-12
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A5, price=B5, tax=C5, usingStartDate=D5, homeTown=E5, species=F5, ageAvg=G5, apprentice=H5}, parent=null, userName=Anakin Skywalker, price=120001, tax=1.08, usingStartDate=Sat Mar 02 00:00:00 JST 2019, homeTown=Tatween, species=Mensch, ageAvg=100, apprentice=Asoka Tano)
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A6, price=B6, tax=C6, usingStartDate=D6, homeTown=E6, species=F6, ageAvg=G6, apprentice=H6}, parent=null, userName=Padme Amidara, price=120002, tax=2.08, usingStartDate=Sun Mar 03 00:00:00 JST 2019, homeTown=Naboo, species=Mensch, ageAvg=100, apprentice=--)
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A7, price=B7, tax=C7, usingStartDate=D7, homeTown=E7, species=F7, ageAvg=G7, apprentice=H7}, parent=null, userName=Luke Skywalker, price=120003, tax=3.08, usingStartDate=Mon Mar 04 00:00:00 JST 2019, homeTown=Polizei Masa, species=Mensch, ageAvg=100, apprentice=Kairo Ren)
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A8, price=B8, tax=C8, usingStartDate=D8, homeTown=E8, species=F8, ageAvg=G8, apprentice=H8}, parent=null, userName=Kairo Ren, price=120004, tax=4.08, usingStartDate=Tue Mar 05 00:00:00 JST 2019, homeTown=Chandrila, species=Mensch, ageAvg=100, apprentice=--)
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A9, price=B9, tax=C9, usingStartDate=D9, homeTown=E9, species=F9, ageAvg=G9, apprentice=H9}, parent=null, userName=Asoka Tano, price=120005, tax=5.08, usingStartDate=Wed Mar 06 00:00:00 JST 2019, homeTown=Siri, species=Togruta, ageAvg=100, apprentice=--)
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A10, price=B10, tax=C10, usingStartDate=D10, homeTown=E10, species=F10, ageAvg=G10, apprentice=H10}, parent=null, userName=Darth Mall, price=120006, tax=6.08, usingStartDate=Thu Mar 07 00:00:00 JST 2019, homeTown=Dasomia, species=Zabrak, ageAvg=null, apprentice=Wilde Opres)
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A11, price=B11, tax=C11, usingStartDate=D11, homeTown=E11, species=F11, ageAvg=G11, apprentice=H11}, parent=null, userName=Yoda, price=120007, tax=7.08, usingStartDate=Fri Mar 08 00:00:00 JST 2019, homeTown=--, species=Yodaの種族, ageAvg=800, apprentice=Luke Skywalker)
com.example.demo.service.DemoService : UsingListRecord(positions={userName=A12, price=B12, tax=C12, usingStartDate=D12, homeTown=E12, species=F12, ageAvg=G12, apprentice=H12}, parent=null, userName=gesamt, price=840028, tax=null, usingStartDate=null, homeTown=--, species=null, ageAvg=null, apprentice=--)
Ich habe festgestellt, dass es implementiert wurde, aber es ist auch gut, dass der Abschlussprozess nicht erforderlich ist. Dieses Mal wurde es etwas kompliziert, da der Prozess zum Ausgeben der Formel (Gesamtzeile) im endgültigen Datensatz enthalten ist. Wenn jedoch keine Formel vorhanden ist, ist die Methode sowohl für die Blatt- als auch für die Datensatzklasse nicht erforderlich, und die Annotation wird reduziert und ist recht einfach. Werden.
Recommended Posts