Skip to content

Commit 862f009

Browse files
author
Olivier Chédru
authored
Merge pull request #303 from d22/master
Refactor: Use own model for header and footer, improve XML escaping
2 parents f91760e + b3fdc42 commit 862f009

File tree

9 files changed

+305
-110
lines changed

9 files changed

+305
-110
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ name: build
22
on:
33
push:
44
branches: [ '*' ]
5-
tags: [ '*' ]
65
pull_request:
76
branches: [ '*' ]
87
jobs:
@@ -15,21 +14,4 @@ jobs:
1514
distribution: 'zulu'
1615
java-version: '8'
1716
- name: maven build
18-
env:
19-
GPG_SECRET_KEY: ${{ secrets.GPG_SECRET_KEY }}
20-
GPG_OWNERTRUST: ${{ secrets.GPG_OWNERTRUST }}
21-
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
22-
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
23-
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
24-
run: |
25-
if echo "${GITHUB_REF_NAME}" | egrep '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?$'
26-
then
27-
# the tag looks like a version number: proceed with release
28-
echo ${GPG_SECRET_KEY} | base64 --decode | gpg --import --no-tty --batch --yes
29-
echo ${GPG_OWNERTRUST} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes
30-
mvn -ntp versions:set -DnewVersion=${GITHUB_REF_NAME}
31-
mvn -ntp -s .github/settings.xml -Prelease deploy
32-
else
33-
# this is a regular build
34-
mvn -ntp install
35-
fi
17+
run: mvn --batch-mode --errors --show-version --no-transfer-progress clean verify

.github/workflows/release.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: release
2+
on:
3+
push:
4+
tags: [ '*' ]
5+
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
- uses: actions/setup-java@v3
12+
with:
13+
distribution: 'zulu'
14+
java-version: '8'
15+
- name: maven release
16+
env:
17+
GPG_SECRET_KEY: ${{ secrets.GPG_SECRET_KEY }}
18+
GPG_OWNERTRUST: ${{ secrets.GPG_OWNERTRUST }}
19+
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
20+
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
21+
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
22+
run: |
23+
if echo "${GITHUB_REF_NAME}" | egrep '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?$'
24+
then
25+
# the tag looks like a version number: proceed with release
26+
echo ${GPG_SECRET_KEY} | base64 --decode | gpg --import --no-tty --batch --yes
27+
echo ${GPG_OWNERTRUST} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes
28+
mvn --batch-mode --errors --show-version --no-transfer-progress versions:set -DnewVersion=${GITHUB_REF_NAME}
29+
mvn --batch-mode --errors --show-version --no-transfer-progress --settings .github/settings.xml -Prelease deploy
30+
fi

fastexcel-writer/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
<artifactId>junit-jupiter-engine</artifactId>
3131
<scope>test</scope>
3232
</dependency>
33+
<dependency>
34+
<groupId>org.junit.jupiter</groupId>
35+
<artifactId>junit-jupiter-params</artifactId>
36+
<scope>test</scope>
37+
</dependency>
3338
<dependency>
3439
<groupId>org.assertj</groupId>
3540
<artifactId>assertj-core</artifactId>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.dhatim.fastexcel;
2+
3+
import java.io.IOException;
4+
5+
/**
6+
* Marginal Information, represents a header or footer
7+
* in an Excel file.
8+
*/
9+
public class MarginalInformation {
10+
11+
private static final String DEFAULT_FONT = "Times New Roman";
12+
private static final int DEFAULT_FONT_SIZE = 12;
13+
private final String text;
14+
private final Position position;
15+
private final String font;
16+
private final int fontSize;
17+
18+
public MarginalInformation(String text, Position position) {
19+
this(text, position, DEFAULT_FONT, DEFAULT_FONT_SIZE);
20+
}
21+
22+
private MarginalInformation(String text, Position position, String font, int fontSize) {
23+
this.text = text;
24+
this.position = position;
25+
this.font = font;
26+
this.fontSize = fontSize;
27+
}
28+
29+
public MarginalInformation withFont(String font) {
30+
return new MarginalInformation(this.text, this.position, font, fontSize);
31+
}
32+
33+
public MarginalInformation withFontSize(int fontSize) {
34+
return new MarginalInformation(this.text, this.position, this.font, fontSize);
35+
}
36+
37+
public String getContent() {
38+
return "&amp;" + position.getPos() +
39+
"&amp;&quot;" + font + ",Regular&quot;&amp;" + fontSize +
40+
"&amp;K000000" + prepareTextForXml(text);
41+
}
42+
43+
public void write(Writer writer) throws IOException {
44+
writer.append(getContent());
45+
}
46+
47+
private String prepareTextForXml(String text) {
48+
switch (text.toLowerCase()) {
49+
case "page 1 of ?":
50+
return "Page &amp;P of &amp;N";
51+
case "page 1, sheetname":
52+
return "Page &amp;P, &amp;A";
53+
case "page 1":
54+
return "Page &amp;P";
55+
case "sheetname":
56+
return "&amp;A";
57+
default:
58+
XmlEscapeHelper xmlEscapeHelper = new XmlEscapeHelper();
59+
return xmlEscapeHelper.escape(text);
60+
}
61+
}
62+
}

fastexcel-writer/src/main/java/org/dhatim/fastexcel/Worksheet.java

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ public class Worksheet implements Closeable {
206206
/**
207207
* Header map for left, central and right field text.
208208
*/
209-
private Map<Position,String> header = new LinkedHashMap();
209+
private final Map<Position, MarginalInformation> header = new LinkedHashMap<>();
210210
/**
211211
* Footer map for left, central and right field text.
212212
*/
213-
private Map<Position,String> footer = new LinkedHashMap();
213+
private final Map<Position, MarginalInformation> footer = new LinkedHashMap<>();
214214
/**
215215
* Range of repeating rows for the print setup.
216216
* (Those rows will be repeated on each page when document is printed.)
@@ -907,14 +907,14 @@ public void finish() throws IOException {
907907
/* write to header and footer */
908908
writer.append("<headerFooter differentFirst=\"false\" differentOddEven=\"false\">");
909909
writer.append("<oddHeader>");
910-
if (header.get(Position.LEFT) != null) writer.append(header.get(Position.LEFT));
911-
if (header.get(Position.CENTER) != null) writer.append(header.get(Position.CENTER));
912-
if (header.get(Position.RIGHT) != null) writer.append(header.get(Position.RIGHT));
910+
for (MarginalInformation headerEntry : header.values()) {
911+
headerEntry.write(writer);
912+
}
913913
writer.append("</oddHeader>");
914914
writer.append("<oddFooter>");
915-
if (footer.get(Position.LEFT) != null) writer.append(footer.get(Position.LEFT));
916-
if (footer.get(Position.CENTER) != null) writer.append(footer.get(Position.CENTER));
917-
if (footer.get(Position.RIGHT) != null) writer.append(footer.get(Position.RIGHT));
915+
for (MarginalInformation footerEntry : footer.values()) {
916+
footerEntry.write(writer);
917+
}
918918
writer.append("</oddFooter></headerFooter>");
919919

920920

@@ -1266,35 +1266,13 @@ public void repeatCols(int col) {
12661266
this.repeatingCols = new RepeatColRange(col, col);
12671267
}
12681268

1269-
/**
1270-
* Gets input text form and converts it into what will be written in the
1271-
* <header>/<footer> xml tag
1272-
* @param text Header/footer text input form
1273-
* @return (partial) String content of <header> or <footer> XML tag
1274-
*/
1275-
private String prepareForXml(String text) {
1276-
switch(text.toLowerCase()) {
1277-
case "page 1 of ?":
1278-
return "Page &amp;P of &amp;N";
1279-
case "page 1, sheetname":
1280-
return "Page &amp;P, &amp;A";
1281-
case "page 1":
1282-
return "Page &amp;P";
1283-
case "sheetname":
1284-
return "&amp;A";
1285-
default:
1286-
return text;
1287-
}
1288-
}
1289-
12901269
/**
12911270
* Set footer text.
12921271
* @param text - text input form or custom text
12931272
* @param position - Position.LEFT/RIGHT/CENTER enum
12941273
*/
12951274
public void footer(String text, Position position) {
1296-
this.footer.put(position, "&amp;" + position.getPos() +
1297-
prepareForXml(text));
1275+
this.footer.put(position, new MarginalInformation(text, position));
12981276
}
12991277

13001278
/**
@@ -1304,9 +1282,8 @@ public void footer(String text, Position position) {
13041282
* @param fontSize - integer describing font size
13051283
*/
13061284
public void footer(String text, Position position, int fontSize) {
1307-
this.footer.put(position, "&amp;" + position.getPos() +
1308-
"&amp;&quot;Times New Roman,Regular&quot;&amp;" + fontSize +
1309-
"&amp;K000000" + prepareForXml(text));
1285+
this.footer.put(position, new MarginalInformation(text, position)
1286+
.withFontSize(fontSize));
13101287
}
13111288

13121289
/**
@@ -1317,9 +1294,9 @@ public void footer(String text, Position position, int fontSize) {
13171294
* @param fontSize - integer describing font size
13181295
*/
13191296
public void footer(String text, Position position, String fontName, int fontSize) {
1320-
this.footer.put(position, "&amp;" + position.getPos() +
1321-
"&amp;&quot;" + fontName + ",Regular&quot;&amp;" + fontSize +
1322-
"&amp;K000000" + prepareForXml(text));
1297+
this.footer.put(position, new MarginalInformation(text, position)
1298+
.withFont(fontName)
1299+
.withFontSize(fontSize));
13231300
}
13241301

13251302
/**
@@ -1330,9 +1307,9 @@ public void footer(String text, Position position, String fontName, int fontSize
13301307
* @param fontSize - integer describing font size
13311308
*/
13321309
public void header(String text, Position position, String fontName, int fontSize) {
1333-
this.header.put(position, "&amp;" + position.getPos() +
1334-
"&amp;&quot;" + fontName + ",Regular&quot;&amp;" + fontSize +
1335-
"&amp;K000000" + prepareForXml(text));
1310+
this.header.put(position, new MarginalInformation(text, position)
1311+
.withFont(fontName)
1312+
.withFontSize(fontSize));
13361313
}
13371314

13381315
/**
@@ -1342,9 +1319,8 @@ public void header(String text, Position position, String fontName, int fontSize
13421319
* @param fontSize - integer describing font size
13431320
*/
13441321
public void header(String text, Position position, int fontSize) {
1345-
this.header.put(position, "&amp;" + position.getPos() +
1346-
"&amp;&quot;Times New Roman,Regular&quot;&amp;" + fontSize +
1347-
"&amp;K000000" + prepareForXml(text));
1322+
this.header.put(position, new MarginalInformation(text, position)
1323+
.withFontSize(fontSize));
13481324
}
13491325

13501326
/**
@@ -1353,8 +1329,7 @@ public void header(String text, Position position, int fontSize) {
13531329
* @param position - Position.LEFT/RIGHT/CENTER enum
13541330
*/
13551331
public void header(String text, Position position) {
1356-
this.header.put(position, "&amp;" + position.getPos() +
1357-
prepareForXml(text));
1332+
this.header.put(position, new MarginalInformation(text, position));
13581333
}
13591334

13601335
/**

fastexcel-writer/src/main/java/org/dhatim/fastexcel/Writer.java

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -65,61 +65,18 @@ Writer appendEscaped(String s) throws IOException {
6565
return append(s, true);
6666
}
6767

68-
/**
69-
* Append a char with XML escaping. Invalid characters in XML 1.0 are
70-
* ignored.
71-
*
72-
* @param c Character code point.
73-
*/
74-
private void escape(int c) {
75-
if (!(c == 0x9 || c == 0xa || c == 0xD
76-
|| (c >= 0x20 && c <= 0xd7ff)
77-
|| (c >= 0xe000 && c <= 0xfffd)
78-
|| (c >= 0x10000 && c <= 0x10ffff))) {
79-
return;
80-
}
81-
switch (c) {
82-
case '<':
83-
sb.append("&lt;");
84-
break;
85-
case '>':
86-
sb.append("&gt;");
87-
break;
88-
case '&':
89-
sb.append("&amp;");
90-
break;
91-
case '\'':
92-
sb.append("&apos;");
93-
break;
94-
case '"':
95-
sb.append("&quot;");
96-
break;
97-
default:
98-
if (c > 0x7e || c < 0x20) {
99-
sb.append("&#x").append(Integer.toHexString(c)).append(';');
100-
} else {
101-
sb.append((char) c);
102-
}
103-
break;
104-
}
105-
}
106-
10768
/**
10869
* Append a string with or without escaping.
10970
*
11071
* @param s String.
111-
* @param escape Is the string escaped?
72+
* @param escape Whether the string should be escaped or not
11273
* @return This writer.
11374
* @throws IOException If an I/O error occurs.
11475
*/
11576
private Writer append(String s, boolean escape) throws IOException {
11677
if (escape) {
117-
int offset = 0;
118-
while (offset < s.length()) {
119-
int codePoint = s.codePointAt(offset);
120-
escape(codePoint);
121-
offset += Character.charCount(codePoint);
122-
}
78+
XmlEscapeHelper xmlEscapeHelper = new XmlEscapeHelper();
79+
sb.append(xmlEscapeHelper.escape(s));
12380
} else {
12481
sb.append(s);
12582
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.dhatim.fastexcel;
2+
3+
/**
4+
* Helper which can apply XML escaping to a string
5+
*/
6+
public class XmlEscapeHelper {
7+
8+
/**
9+
* Apply XML escaping to a String.
10+
* Invalid characters in XML 1.0 are ignored.
11+
*
12+
* @param text text to be escaped
13+
* @return escaped text
14+
*/
15+
public String escape(final String text) {
16+
int offset = 0;
17+
StringBuilder sb = new StringBuilder();
18+
while (offset < text.length()) {
19+
int codePoint = text.codePointAt(offset);
20+
sb.append(escape(codePoint));
21+
offset += Character.charCount(codePoint);
22+
}
23+
return sb.toString();
24+
}
25+
26+
/**
27+
* Escape char with XML escaping.
28+
* Invalid characters in XML 1.0 are ignored.
29+
*
30+
* @param c Character code point.
31+
*/
32+
private String escape(int c) {
33+
if (!(c == 0x9 || c == 0xa || c == 0xD
34+
|| (c >= 0x20 && c <= 0xd7ff)
35+
|| (c >= 0xe000 && c <= 0xfffd)
36+
|| (c >= 0x10000 && c <= 0x10ffff))) {
37+
return "";
38+
}
39+
switch (c) {
40+
case '<':
41+
return "&lt;";
42+
case '>':
43+
return "&gt;";
44+
case '&':
45+
return "&amp;";
46+
case '\'':
47+
return "&apos;";
48+
case '"':
49+
return "&quot;";
50+
default:
51+
if (c > 0x7e || c < 0x20) {
52+
return "&#x".concat(Integer.toHexString(c)).concat(";");
53+
} else {
54+
return String.valueOf((char) c);
55+
}
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)