mirror of https://github.com/apache/poi.git
Sonar Fixes
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1870856 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
08159e66a7
commit
9f2f9dc793
|
@ -20,18 +20,18 @@ package org.apache.poi.hssf.usermodel.examples;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
||||||
import org.apache.poi.ss.util.CellReference;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
|
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
|
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
|
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
|
||||||
|
import org.apache.poi.ss.util.CellReference;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,8 +126,8 @@ import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
|
||||||
* A note concerning Excels' image resizing behaviour. The HSSFClientAnchor
|
* A note concerning Excels' image resizing behaviour. The HSSFClientAnchor
|
||||||
* class contains a method called setAnchorType(int) which can be used to
|
* class contains a method called setAnchorType(int) which can be used to
|
||||||
* determine how Excel will resize an image in reponse to the user increasing
|
* determine how Excel will resize an image in reponse to the user increasing
|
||||||
* or decreasing the dimensions of the cell containing the image. There are
|
* or decreasing the dimensions of the cell containing the image. There are
|
||||||
* three values that can be passed to this method; 0 = To move and size the
|
* three values that can be passed to this method; 0 = To move and size the
|
||||||
* image with the cell, 2 = To move but don't size the image with the cell,
|
* image with the cell, 2 = To move but don't size the image with the cell,
|
||||||
* 3 = To prevent the image from moving or being resized along with the cell. If
|
* 3 = To prevent the image from moving or being resized along with the cell. If
|
||||||
* an image is inserted using this class and placed into a single cell then if
|
* an image is inserted using this class and placed into a single cell then if
|
||||||
|
@ -298,7 +298,7 @@ public class AddDimensionedImage {
|
||||||
// become another parameter passed to the method.
|
// become another parameter passed to the method.
|
||||||
//anchor.setAnchorType(HSSFClientAnchor.DONT_MOVE_AND_RESIZE);
|
//anchor.setAnchorType(HSSFClientAnchor.DONT_MOVE_AND_RESIZE);
|
||||||
anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);
|
anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);
|
||||||
|
|
||||||
// Now, add the picture to the workbook. Note that the type is assumed
|
// Now, add the picture to the workbook. Note that the type is assumed
|
||||||
// to be a JPEG/JPG, this could easily (and should) be parameterised
|
// to be a JPEG/JPG, this could easily (and should) be parameterised
|
||||||
// however.
|
// however.
|
||||||
|
@ -538,7 +538,7 @@ public class AddDimensionedImage {
|
||||||
// total number of co-ordinate positions to the third paramater
|
// total number of co-ordinate positions to the third paramater
|
||||||
// of the ClientAnchorDetail constructor. For no sepcific reason,
|
// of the ClientAnchorDetail constructor. For no sepcific reason,
|
||||||
// the latter option is used below.
|
// the latter option is used below.
|
||||||
anchorDetail = new ClientAnchorDetail(startingColumn,
|
anchorDetail = new ClientAnchorDetail(startingColumn,
|
||||||
toColumn, ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS);
|
toColumn, ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS);
|
||||||
}
|
}
|
||||||
// In this case, the image will overlap part of another column and it is
|
// In this case, the image will overlap part of another column and it is
|
||||||
|
@ -675,29 +675,9 @@ public class AddDimensionedImage {
|
||||||
* interrupted.
|
* interrupted.
|
||||||
*/
|
*/
|
||||||
private byte[] imageToBytes(String imageFilename) throws IOException {
|
private byte[] imageToBytes(String imageFilename) throws IOException {
|
||||||
File imageFile;
|
File imageFile = new File(imageFilename);
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(imageFile)) {
|
||||||
ByteArrayOutputStream bos;
|
return IOUtils.toByteArray(fis);
|
||||||
int read;
|
|
||||||
try {
|
|
||||||
imageFile = new File(imageFilename);
|
|
||||||
fis = new FileInputStream(imageFile);
|
|
||||||
bos = new ByteArrayOutputStream();
|
|
||||||
while((read = fis.read()) != -1) {
|
|
||||||
bos.write(read);
|
|
||||||
}
|
|
||||||
return(bos.toByteArray());
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if(fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
fis = null;
|
|
||||||
}
|
|
||||||
catch(IOException ioEx) {
|
|
||||||
// Nothing to do here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,41 +700,21 @@ public class AddDimensionedImage {
|
||||||
*
|
*
|
||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) throws IOException {
|
||||||
String imageFile;
|
if(args.length < 2){
|
||||||
String outputFile;
|
System.err.println("Usage: AddDimensionedImage imageFile outputFile");
|
||||||
FileOutputStream fos = null;
|
return;
|
||||||
HSSFSheet sheet;
|
|
||||||
try {
|
|
||||||
if(args.length < 2){
|
|
||||||
System.err.println("Usage: AddDimensionedImage imageFile outputFile");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
imageFile = args[0];
|
|
||||||
outputFile = args[1];
|
|
||||||
|
|
||||||
try (HSSFWorkbook workbook = new HSSFWorkbook()) {
|
|
||||||
sheet = workbook.createSheet("Picture Test");
|
|
||||||
new AddDimensionedImage().addImageToSheet("A1", sheet,
|
|
||||||
imageFile, 125, 125,
|
|
||||||
AddDimensionedImage.EXPAND_ROW_AND_COLUMN);
|
|
||||||
fos = new FileOutputStream(outputFile);
|
|
||||||
workbook.write(fos);
|
|
||||||
}
|
|
||||||
} catch(IOException ioEx) {
|
|
||||||
System.out.println("Caught an: " + ioEx.getClass().getName());
|
|
||||||
System.out.println("Message: " + ioEx.getMessage());
|
|
||||||
System.out.println("Stacktrace follows...........");
|
|
||||||
ioEx.printStackTrace(System.out);
|
|
||||||
}
|
}
|
||||||
finally {
|
String imageFile = args[0];
|
||||||
try {
|
String outputFile = args[1];
|
||||||
if(fos != null) {
|
|
||||||
fos.close();
|
try (HSSFWorkbook workbook = new HSSFWorkbook()) {
|
||||||
fos = null;
|
HSSFSheet sheet = workbook.createSheet("Picture Test");
|
||||||
}
|
new AddDimensionedImage().addImageToSheet("A1", sheet,
|
||||||
} catch(IOException ioEx) {
|
imageFile, 125, 125,
|
||||||
// I G N O R E
|
AddDimensionedImage.EXPAND_ROW_AND_COLUMN);
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
|
||||||
|
workbook.write(fos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -775,21 +735,21 @@ public class AddDimensionedImage {
|
||||||
* * Together, parameter seven and eight determine the column and row
|
* * Together, parameter seven and eight determine the column and row
|
||||||
* co-ordinates of the cell whose top left hand corner will be aligned
|
* co-ordinates of the cell whose top left hand corner will be aligned
|
||||||
* with the images bottom right hand corner.
|
* with the images bottom right hand corner.
|
||||||
*
|
*
|
||||||
* An instance of the ClientAnchorDetail class provides three of the eight
|
* An instance of the ClientAnchorDetail class provides three of the eight
|
||||||
* parameters, one of the co-ordinates for the images top left hand corner,
|
* parameters, one of the co-ordinates for the images top left hand corner,
|
||||||
* one of the co-ordinates for the images bottom right hand corner and
|
* one of the co-ordinates for the images bottom right hand corner and
|
||||||
* either how far the image should be inset from the top or the left hand
|
* either how far the image should be inset from the top or the left hand
|
||||||
* edge of the cell.
|
* edge of the cell.
|
||||||
*
|
*
|
||||||
* @author Mark Beardsley [mas at apache.org]
|
* @author Mark Beardsley [mas at apache.org]
|
||||||
* @version 1.00 5th August 2009.
|
* @version 1.00 5th August 2009.
|
||||||
*/
|
*/
|
||||||
public class ClientAnchorDetail {
|
public static class ClientAnchorDetail {
|
||||||
|
|
||||||
public int fromIndex;
|
private int fromIndex;
|
||||||
public int toIndex;
|
private int toIndex;
|
||||||
public int inset;
|
private int inset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the ClientAnchorDetail class using the
|
* Create a new instance of the ClientAnchorDetail class using the
|
||||||
|
@ -857,17 +817,13 @@ public class AddDimensionedImage {
|
||||||
* Additional constants.
|
* Additional constants.
|
||||||
* widthUnits2Millimetres() and millimetres2Units() methods.
|
* widthUnits2Millimetres() and millimetres2Units() methods.
|
||||||
*/
|
*/
|
||||||
public static class ConvertImageUnits {
|
private static final class ConvertImageUnits {
|
||||||
|
|
||||||
// Each cell conatins a fixed number of co-ordinate points; this number
|
// Each cell conatins a fixed number of co-ordinate points; this number
|
||||||
// does not vary with row height or column width or with font. These two
|
// does not vary with row height or column width or with font. These two
|
||||||
// constants are defined below.
|
// constants are defined below.
|
||||||
public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023; // MB
|
public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023; // MB
|
||||||
public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255; // MB
|
public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255; // MB
|
||||||
// The resoultion of an image can be expressed as a specific number
|
|
||||||
// of pixels per inch. Displays and printers differ but 96 pixels per
|
|
||||||
// inch is an acceptable standard to beging with.
|
|
||||||
public static final int PIXELS_PER_INCH = 96; // MB
|
|
||||||
// Cnstants that defines how many pixels and points there are in a
|
// Cnstants that defines how many pixels and points there are in a
|
||||||
// millimetre. These values are required for the conversion algorithm.
|
// millimetre. These values are required for the conversion algorithm.
|
||||||
public static final double PIXELS_PER_MILLIMETRES = 3.78; // MB
|
public static final double PIXELS_PER_MILLIMETRES = 3.78; // MB
|
||||||
|
@ -880,13 +836,11 @@ public class AddDimensionedImage {
|
||||||
public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D; // MB
|
public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D; // MB
|
||||||
public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
||||||
public static final int UNIT_OFFSET_LENGTH = 7;
|
public static final int UNIT_OFFSET_LENGTH = 7;
|
||||||
public static final int[] UNIT_OFFSET_MAP = new int[]
|
private static final int[] UNIT_OFFSET_MAP = new int[]
|
||||||
{ 0, 36, 73, 109, 146, 182, 219 };
|
{ 0, 36, 73, 109, 146, 182, 219 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pixel units to excel width units(units of 1/256th of a character width)
|
* pixel units to excel width units(units of 1/256th of a character width)
|
||||||
* @param pxs
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static short pixel2WidthUnits(int pxs) {
|
public static short pixel2WidthUnits(int pxs) {
|
||||||
short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR *
|
short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR *
|
||||||
|
@ -898,9 +852,6 @@ public class AddDimensionedImage {
|
||||||
/**
|
/**
|
||||||
* excel width units(units of 1/256th of a character width) to pixel
|
* excel width units(units of 1/256th of a character width) to pixel
|
||||||
* units.
|
* units.
|
||||||
*
|
|
||||||
* @param widthUnits
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static int widthUnits2Pixel(short widthUnits) {
|
public static int widthUnits2Pixel(short widthUnits) {
|
||||||
int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR)
|
int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR)
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.apache.poi.hssf.usermodel.examples;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||||
|
@ -57,7 +56,8 @@ public final class HSSFReadWrite {
|
||||||
* rows/cells.
|
* rows/cells.
|
||||||
*/
|
*/
|
||||||
private static void testCreateSampleSheet(String outputFilename) throws IOException {
|
private static void testCreateSampleSheet(String outputFilename) throws IOException {
|
||||||
try (HSSFWorkbook wb = new HSSFWorkbook()) {
|
try (HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
|
FileOutputStream out = new FileOutputStream(outputFilename)) {
|
||||||
HSSFSheet s = wb.createSheet();
|
HSSFSheet s = wb.createSheet();
|
||||||
HSSFCellStyle cs = wb.createCellStyle();
|
HSSFCellStyle cs = wb.createCellStyle();
|
||||||
HSSFCellStyle cs2 = wb.createCellStyle();
|
HSSFCellStyle cs2 = wb.createCellStyle();
|
||||||
|
@ -121,9 +121,7 @@ public final class HSSFReadWrite {
|
||||||
wb.removeSheetAt(1);
|
wb.removeSheetAt(1);
|
||||||
|
|
||||||
// end deleted sheet
|
// end deleted sheet
|
||||||
try (FileOutputStream out = new FileOutputStream(outputFilename)) {
|
wb.write(out);
|
||||||
wb.write(out);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,115 +145,104 @@ public final class HSSFReadWrite {
|
||||||
* "MODIFIED CELL" then writes it out. Hence this is "modify test 1". If you
|
* "MODIFIED CELL" then writes it out. Hence this is "modify test 1". If you
|
||||||
* take the output from the write test, you'll have a valid scenario.
|
* take the output from the write test, you'll have a valid scenario.
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) throws Exception {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
System.err.println("At least one argument expected");
|
System.err.println("At least one argument expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String fileName = args[0];
|
String fileName = args[0];
|
||||||
try {
|
if (args.length < 2) {
|
||||||
if (args.length < 2) {
|
|
||||||
|
|
||||||
try (HSSFWorkbook wb = HSSFReadWrite.readFile(fileName)) {
|
try (HSSFWorkbook wb = HSSFReadWrite.readFile(fileName)) {
|
||||||
System.out.println("Data dump:\n");
|
System.out.println("Data dump:\n");
|
||||||
|
|
||||||
for (int k = 0; k < wb.getNumberOfSheets(); k++) {
|
for (int k = 0; k < wb.getNumberOfSheets(); k++) {
|
||||||
HSSFSheet sheet = wb.getSheetAt(k);
|
HSSFSheet sheet = wb.getSheetAt(k);
|
||||||
int rows = sheet.getPhysicalNumberOfRows();
|
int rows = sheet.getPhysicalNumberOfRows();
|
||||||
System.out.println("Sheet " + k + " \"" + wb.getSheetName(k) + "\" has " + rows
|
System.out.println("Sheet " + k + " \"" + wb.getSheetName(k) + "\" has " + rows + " row(s).");
|
||||||
+ " row(s).");
|
for (int r = 0; r < rows; r++) {
|
||||||
for (int r = 0; r < rows; r++) {
|
HSSFRow row = sheet.getRow(r);
|
||||||
HSSFRow row = sheet.getRow(r);
|
if (row == null) {
|
||||||
if (row == null) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("\nROW " + row.getRowNum() + " has " + row.getPhysicalNumberOfCells() + " cell(s).");
|
System.out.println("\nROW " + row.getRowNum() + " has " + row.getPhysicalNumberOfCells() + " cell(s).");
|
||||||
for (int c = 0; c < row.getLastCellNum(); c++) {
|
for (int c = 0; c < row.getLastCellNum(); c++) {
|
||||||
HSSFCell cell = row.getCell(c);
|
HSSFCell cell = row.getCell(c);
|
||||||
String value;
|
String value;
|
||||||
|
|
||||||
if (cell != null) {
|
if (cell != null) {
|
||||||
switch (cell.getCellType()) {
|
switch (cell.getCellType()) {
|
||||||
|
|
||||||
case FORMULA:
|
case FORMULA:
|
||||||
value = "FORMULA value=" + cell.getCellFormula();
|
value = "FORMULA value=" + cell.getCellFormula();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NUMERIC:
|
case NUMERIC:
|
||||||
value = "NUMERIC value=" + cell.getNumericCellValue();
|
value = "NUMERIC value=" + cell.getNumericCellValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
value = "STRING value=" + cell.getStringCellValue();
|
value = "STRING value=" + cell.getStringCellValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLANK:
|
case BLANK:
|
||||||
value = "<BLANK>";
|
value = "<BLANK>";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
value = "BOOLEAN value-" + cell.getBooleanCellValue();
|
value = "BOOLEAN value-" + cell.getBooleanCellValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ERROR:
|
case ERROR:
|
||||||
value = "ERROR value=" + cell.getErrorCellValue();
|
value = "ERROR value=" + cell.getErrorCellValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
value = "UNKNOWN value of type " + cell.getCellType();
|
value = "UNKNOWN value of type " + cell.getCellType();
|
||||||
}
|
|
||||||
System.out.println("CELL col=" + cell.getColumnIndex() + " VALUE="
|
|
||||||
+ value);
|
|
||||||
}
|
}
|
||||||
|
System.out.println("CELL col=" + cell.getColumnIndex() + " VALUE=" + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (args.length == 2) {
|
|
||||||
if (args[1].toLowerCase(Locale.ROOT).equals("write")) {
|
|
||||||
System.out.println("Write mode");
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
HSSFReadWrite.testCreateSampleSheet(fileName);
|
|
||||||
|
|
||||||
System.out.println("" + (System.currentTimeMillis() - time)
|
|
||||||
+ " ms generation time");
|
|
||||||
} else {
|
|
||||||
System.out.println("readwrite test");
|
|
||||||
try (HSSFWorkbook wb = HSSFReadWrite.readFile(fileName)) {
|
|
||||||
try (FileOutputStream stream = new FileOutputStream(args[1])) {
|
|
||||||
wb.write(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (args.length == 3 && args[2].equalsIgnoreCase("modify1")) {
|
|
||||||
// delete row 0-24, row 74 - 99 && change cell 3 on row 39 to string "MODIFIED CELL!!"
|
|
||||||
|
|
||||||
try (HSSFWorkbook wb = HSSFReadWrite.readFile(fileName)) {
|
|
||||||
HSSFSheet sheet = wb.getSheetAt(0);
|
|
||||||
|
|
||||||
for (int k = 0; k < 25; k++) {
|
|
||||||
HSSFRow row = sheet.getRow(k);
|
|
||||||
|
|
||||||
sheet.removeRow(row);
|
|
||||||
}
|
|
||||||
for (int k = 74; k < 100; k++) {
|
|
||||||
HSSFRow row = sheet.getRow(k);
|
|
||||||
|
|
||||||
sheet.removeRow(row);
|
|
||||||
}
|
|
||||||
HSSFRow row = sheet.getRow(39);
|
|
||||||
HSSFCell cell = row.getCell(3);
|
|
||||||
cell.setCellValue("MODIFIED CELL!!!!!");
|
|
||||||
|
|
||||||
try (FileOutputStream stream = new FileOutputStream(args[1])) {
|
|
||||||
wb.write(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} else if (args.length == 2) {
|
||||||
e.printStackTrace();
|
if ("write".equalsIgnoreCase(args[1])) {
|
||||||
|
System.out.println("Write mode");
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
HSSFReadWrite.testCreateSampleSheet(fileName);
|
||||||
|
|
||||||
|
System.out.println("" + (System.currentTimeMillis() - time) + " ms generation time");
|
||||||
|
} else {
|
||||||
|
System.out.println("readwrite test");
|
||||||
|
try (HSSFWorkbook wb = HSSFReadWrite.readFile(fileName);
|
||||||
|
FileOutputStream stream = new FileOutputStream(args[1])) {
|
||||||
|
wb.write(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (args.length == 3 && "modify1".equalsIgnoreCase(args[2])) {
|
||||||
|
// delete row 0-24, row 74 - 99 && change cell 3 on row 39 to string "MODIFIED CELL!!"
|
||||||
|
|
||||||
|
try (HSSFWorkbook wb = HSSFReadWrite.readFile(fileName);
|
||||||
|
FileOutputStream stream = new FileOutputStream(args[1])) {
|
||||||
|
HSSFSheet sheet = wb.getSheetAt(0);
|
||||||
|
|
||||||
|
for (int k = 0; k < 25; k++) {
|
||||||
|
HSSFRow row = sheet.getRow(k);
|
||||||
|
sheet.removeRow(row);
|
||||||
|
}
|
||||||
|
for (int k = 74; k < 100; k++) {
|
||||||
|
HSSFRow row = sheet.getRow(k);
|
||||||
|
sheet.removeRow(row);
|
||||||
|
}
|
||||||
|
HSSFRow row = sheet.getRow(39);
|
||||||
|
HSSFCell cell = row.getCell(3);
|
||||||
|
cell.setCellValue("MODIFIED CELL!!!!!");
|
||||||
|
|
||||||
|
wb.write(stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class SViewer extends JApplet {
|
||||||
* Initialize the applet
|
* Initialize the applet
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("squid:S1148")
|
||||||
public void init() {
|
public void init() {
|
||||||
try {
|
try {
|
||||||
jbInit();
|
jbInit();
|
||||||
|
|
|
@ -17,13 +17,37 @@
|
||||||
|
|
||||||
package org.apache.poi.hssf.view;
|
package org.apache.poi.hssf.view;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.AWTEvent;
|
||||||
import java.awt.event.*;
|
import java.awt.BorderLayout;
|
||||||
import java.io.*;
|
import java.awt.Dimension;
|
||||||
import javax.swing.*;
|
import java.awt.Graphics;
|
||||||
import javax.swing.table.*;
|
import java.awt.Insets;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.poi.hssf.usermodel.*;
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTabbedPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.table.JTableHeader;
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
|
import javax.swing.table.TableColumnModel;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class presents the sheets to the user.
|
* This class presents the sheets to the user.
|
||||||
|
@ -144,7 +168,7 @@ public void paint(Graphics g) {
|
||||||
* The default is to popup a menu when the event occurs over a tab
|
* The default is to popup a menu when the event occurs over a tab
|
||||||
*/
|
*/
|
||||||
private class TabListener implements MouseListener {
|
private class TabListener implements MouseListener {
|
||||||
public JPopupMenu popup;
|
private final JPopupMenu popup;
|
||||||
public TabListener() {
|
public TabListener() {
|
||||||
popup = new JPopupMenu("Sheet");
|
popup = new JPopupMenu("Sheet");
|
||||||
popup.add(createInsertSheetAction());
|
popup.add(createInsertSheetAction());
|
||||||
|
|
|
@ -100,7 +100,7 @@ import org.apache.poi.util.IOUtils;
|
||||||
* in which those corners should be located. The setCol1() and setRow1() methods
|
* in which those corners should be located. The setCol1() and setRow1() methods
|
||||||
* together identify the cell that should contain the top left hand corner of
|
* together identify the cell that should contain the top left hand corner of
|
||||||
* the image while setCol2() and setRow2() do the same for the images bottom
|
* the image while setCol2() and setRow2() do the same for the images bottom
|
||||||
* right hand corner.
|
* right hand corner.
|
||||||
*
|
*
|
||||||
* Knowing that, it is possible to look again at the example above and to see
|
* Knowing that, it is possible to look again at the example above and to see
|
||||||
* that the top left hand corner of the image will be located in cell A1 (0, 0)
|
* that the top left hand corner of the image will be located in cell A1 (0, 0)
|
||||||
|
@ -108,7 +108,7 @@ import org.apache.poi.util.IOUtils;
|
||||||
* the bottom right hand corner of the image will be located in cell B2 (1, 1) and
|
* the bottom right hand corner of the image will be located in cell B2 (1, 1) and
|
||||||
* it will again be aligned with the top left hand corner of the cell. This has the
|
* it will again be aligned with the top left hand corner of the cell. This has the
|
||||||
* effect of making the image seem to occupy the whole of cell A1. Interestingly, it
|
* effect of making the image seem to occupy the whole of cell A1. Interestingly, it
|
||||||
* also has an effect on the images resizing behaviour because testing has
|
* also has an effect on the images resizing behaviour because testing has
|
||||||
* demonstrated that if the image is wholly contained within one cell and is not
|
* demonstrated that if the image is wholly contained within one cell and is not
|
||||||
* 'attached' for want of a better word, to a neighbouring cell, then that image
|
* 'attached' for want of a better word, to a neighbouring cell, then that image
|
||||||
* will not increase in size in response to the user dragging the column wider
|
* will not increase in size in response to the user dragging the column wider
|
||||||
|
@ -170,8 +170,8 @@ import org.apache.poi.util.IOUtils;
|
||||||
* A note concerning Excels image resizing behaviour. The ClientAnchor
|
* A note concerning Excels image resizing behaviour. The ClientAnchor
|
||||||
* class contains a method called setAnchorType(int) which can be used to
|
* class contains a method called setAnchorType(int) which can be used to
|
||||||
* determine how Excel will resize an image in response to the user increasing
|
* determine how Excel will resize an image in response to the user increasing
|
||||||
* or decreasing the dimensions of the cell containing the image. There are
|
* or decreasing the dimensions of the cell containing the image. There are
|
||||||
* three values that can be passed to this method; 0 = To move and size the
|
* three values that can be passed to this method; 0 = To move and size the
|
||||||
* image with the cell, 2 = To move but don't size the image with the cell,
|
* image with the cell, 2 = To move but don't size the image with the cell,
|
||||||
* 3 = To prevent the image from moving or being resized along with the cell. If
|
* 3 = To prevent the image from moving or being resized along with the cell. If
|
||||||
* an image is inserted using this class and placed into a single cell then if
|
* an image is inserted using this class and placed into a single cell then if
|
||||||
|
@ -221,12 +221,12 @@ public class AddDimensionedImage {
|
||||||
public static final int EXPAND_COLUMN = 2;
|
public static final int EXPAND_COLUMN = 2;
|
||||||
public static final int EXPAND_ROW_AND_COLUMN = 3;
|
public static final int EXPAND_ROW_AND_COLUMN = 3;
|
||||||
public static final int OVERLAY_ROW_AND_COLUMN = 7;
|
public static final int OVERLAY_ROW_AND_COLUMN = 7;
|
||||||
|
|
||||||
// Modified to support EMU - English Metric Units - used within the OOXML
|
// Modified to support EMU - English Metric Units - used within the OOXML
|
||||||
// workbooks, this multoplier is used to convert between measurements in
|
// workbooks, this multoplier is used to convert between measurements in
|
||||||
// millimetres and in EMUs
|
// millimetres and in EMUs
|
||||||
private static final int EMU_PER_MM = 36000;
|
private static final int EMU_PER_MM = 36000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an image to a worksheet.
|
* Add an image to a worksheet.
|
||||||
*
|
*
|
||||||
|
@ -551,7 +551,7 @@ public class AddDimensionedImage {
|
||||||
(resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) {
|
(resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) {
|
||||||
row.setHeightInPoints((float)(reqImageHeightMM *
|
row.setHeightInPoints((float)(reqImageHeightMM *
|
||||||
ConvertImageUnits.POINTS_PER_MILLIMETRE));
|
ConvertImageUnits.POINTS_PER_MILLIMETRE));
|
||||||
if(sheet instanceof HSSFSheet) {
|
if(sheet instanceof HSSFSheet) {
|
||||||
rowHeightMM = reqImageHeightMM;
|
rowHeightMM = reqImageHeightMM;
|
||||||
rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
|
rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
|
||||||
rowHeightMM;
|
rowHeightMM;
|
||||||
|
@ -863,9 +863,9 @@ public class AddDimensionedImage {
|
||||||
*/
|
*/
|
||||||
public class ClientAnchorDetail {
|
public class ClientAnchorDetail {
|
||||||
|
|
||||||
public int fromIndex;
|
private int fromIndex;
|
||||||
public int toIndex;
|
private int toIndex;
|
||||||
public int inset;
|
private int inset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the ClientAnchorDetail class using the
|
* Create a new instance of the ClientAnchorDetail class using the
|
||||||
|
@ -938,26 +938,25 @@ public class AddDimensionedImage {
|
||||||
// Each cell conatins a fixed number of co-ordinate points; this number
|
// Each cell conatins a fixed number of co-ordinate points; this number
|
||||||
// does not vary with row height or column width or with font. These two
|
// does not vary with row height or column width or with font. These two
|
||||||
// constants are defined below.
|
// constants are defined below.
|
||||||
public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023; // MB
|
public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023;
|
||||||
public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255; // MB
|
public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255;
|
||||||
// The resoultion of an image can be expressed as a specific number
|
// The resoultion of an image can be expressed as a specific number
|
||||||
// of pixels per inch. Displays and printers differ but 96 pixels per
|
// of pixels per inch. Displays and printers differ but 96 pixels per
|
||||||
// inch is an acceptable standard to beging with.
|
// inch is an acceptable standard to beging with.
|
||||||
public static final int PIXELS_PER_INCH = 96; // MB
|
public static final int PIXELS_PER_INCH = 96;
|
||||||
// Cnstants that defines how many pixels and points there are in a
|
// Cnstants that defines how many pixels and points there are in a
|
||||||
// millimetre. These values are required for the conversion algorithm.
|
// millimetre. These values are required for the conversion algorithm.
|
||||||
public static final double PIXELS_PER_MILLIMETRES = 3.78; // MB
|
public static final double PIXELS_PER_MILLIMETRES = 3.78;
|
||||||
public static final double POINTS_PER_MILLIMETRE = 2.83; // MB
|
public static final double POINTS_PER_MILLIMETRE = 2.83;
|
||||||
// The column width returned by HSSF and the width of a picture when
|
// The column width returned by HSSF and the width of a picture when
|
||||||
// positioned to exactly cover one cell are different by almost exactly
|
// positioned to exactly cover one cell are different by almost exactly
|
||||||
// 2mm - give or take rounding errors. This constant allows that
|
// 2mm - give or take rounding errors. This constant allows that
|
||||||
// additional amount to be accounted for when calculating how many
|
// additional amount to be accounted for when calculating how many
|
||||||
// celles the image ought to overlie.
|
// celles the image ought to overlie.
|
||||||
public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D; // MB
|
public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D;
|
||||||
public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
||||||
public static final int UNIT_OFFSET_LENGTH = 7;
|
public static final int UNIT_OFFSET_LENGTH = 7;
|
||||||
public static final int[] UNIT_OFFSET_MAP = new int[]
|
private static final int[] UNIT_OFFSET_MAP = { 0, 36, 73, 109, 146, 182, 219 };
|
||||||
{ 0, 36, 73, 109, 146, 182, 219 };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pixel units to excel width units(units of 1/256th of a character width)
|
* pixel units to excel width units(units of 1/256th of a character width)
|
||||||
|
@ -1007,13 +1006,5 @@ public class AddDimensionedImage {
|
||||||
return(ConvertImageUnits.pixel2WidthUnits((int)(millimetres *
|
return(ConvertImageUnits.pixel2WidthUnits((int)(millimetres *
|
||||||
ConvertImageUnits.PIXELS_PER_MILLIMETRES)));
|
ConvertImageUnits.PIXELS_PER_MILLIMETRES)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int pointsToPixels(double points) {
|
|
||||||
return (int) Math.round(points / 72D * PIXELS_PER_INCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double pointsToMillimeters(double points) {
|
|
||||||
return points / 72D * 25.4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,16 +52,16 @@ public class CheckFunctionsSupported {
|
||||||
System.err.println(" CheckFunctionsSupported <filename>");
|
System.err.println(" CheckFunctionsSupported <filename>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Workbook wb = WorkbookFactory.create(new File(args[0]));
|
Workbook wb = WorkbookFactory.create(new File(args[0]));
|
||||||
CheckFunctionsSupported check = new CheckFunctionsSupported(wb);
|
CheckFunctionsSupported check = new CheckFunctionsSupported(wb);
|
||||||
|
|
||||||
// Fetch all the problems
|
// Fetch all the problems
|
||||||
List<FormulaEvaluationProblems> problems = new ArrayList<>();
|
List<FormulaEvaluationProblems> problems = new ArrayList<>();
|
||||||
for (int sn=0; sn<wb.getNumberOfSheets(); sn++) {
|
for (int sn=0; sn<wb.getNumberOfSheets(); sn++) {
|
||||||
problems.add(check.getEvaluationProblems(sn));
|
problems.add(check.getEvaluationProblems(sn));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Produce an overall summary
|
// Produce an overall summary
|
||||||
Set<String> unsupportedFunctions = new TreeSet<>();
|
Set<String> unsupportedFunctions = new TreeSet<>();
|
||||||
for (FormulaEvaluationProblems p : problems) {
|
for (FormulaEvaluationProblems p : problems) {
|
||||||
|
@ -76,15 +76,15 @@ public class CheckFunctionsSupported {
|
||||||
}
|
}
|
||||||
System.out.println("Total unsupported functions = " + unsupportedFunctions.size());
|
System.out.println("Total unsupported functions = " + unsupportedFunctions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report sheet by sheet
|
// Report sheet by sheet
|
||||||
for (int sn=0; sn<wb.getNumberOfSheets(); sn++) {
|
for (int sn=0; sn<wb.getNumberOfSheets(); sn++) {
|
||||||
String sheetName = wb.getSheetName(sn);
|
String sheetName = wb.getSheetName(sn);
|
||||||
FormulaEvaluationProblems probs = problems.get(sn);
|
FormulaEvaluationProblems probs = problems.get(sn);
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
System.out.println("Sheet = " + sheetName);
|
System.out.println("Sheet = " + sheetName);
|
||||||
|
|
||||||
if (probs.unevaluatableCells.isEmpty()) {
|
if (probs.unevaluatableCells.isEmpty()) {
|
||||||
System.out.println(" All cells evaluated without error");
|
System.out.println(" All cells evaluated without error");
|
||||||
} else {
|
} else {
|
||||||
|
@ -95,14 +95,14 @@ public class CheckFunctionsSupported {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Workbook workbook;
|
private Workbook workbook;
|
||||||
private FormulaEvaluator evaluator;
|
private FormulaEvaluator evaluator;
|
||||||
public CheckFunctionsSupported(Workbook workbook) {
|
public CheckFunctionsSupported(Workbook workbook) {
|
||||||
this.workbook = workbook;
|
this.workbook = workbook;
|
||||||
this.evaluator = workbook.getCreationHelper().createFormulaEvaluator();
|
this.evaluator = workbook.getCreationHelper().createFormulaEvaluator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getUnsupportedFunctions(String sheetName) {
|
public Set<String> getUnsupportedFunctions(String sheetName) {
|
||||||
return getUnsupportedFunctions(workbook.getSheet(sheetName));
|
return getUnsupportedFunctions(workbook.getSheet(sheetName));
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ public class CheckFunctionsSupported {
|
||||||
FormulaEvaluationProblems problems = getEvaluationProblems(sheet);
|
FormulaEvaluationProblems problems = getEvaluationProblems(sheet);
|
||||||
return problems.unsupportedFunctions;
|
return problems.unsupportedFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FormulaEvaluationProblems getEvaluationProblems(String sheetName) {
|
public FormulaEvaluationProblems getEvaluationProblems(String sheetName) {
|
||||||
return getEvaluationProblems(workbook.getSheet(sheetName));
|
return getEvaluationProblems(workbook.getSheet(sheetName));
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ public class CheckFunctionsSupported {
|
||||||
public FormulaEvaluationProblems getEvaluationProblems(Sheet sheet) {
|
public FormulaEvaluationProblems getEvaluationProblems(Sheet sheet) {
|
||||||
Set<String> unsupportedFunctions = new HashSet<>();
|
Set<String> unsupportedFunctions = new HashSet<>();
|
||||||
Map<CellReference,Exception> unevaluatableCells = new HashMap<>();
|
Map<CellReference,Exception> unevaluatableCells = new HashMap<>();
|
||||||
|
|
||||||
for (Row r : sheet) {
|
for (Row r : sheet) {
|
||||||
for (Cell c : r) {
|
for (Cell c : r) {
|
||||||
try {
|
try {
|
||||||
|
@ -133,7 +133,7 @@ public class CheckFunctionsSupported {
|
||||||
// Has been wrapped with cell details, but we know those
|
// Has been wrapped with cell details, but we know those
|
||||||
e = (Exception)e.getCause();
|
e = (Exception)e.getCause();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e instanceof NotImplementedFunctionException) {
|
if (e instanceof NotImplementedFunctionException) {
|
||||||
NotImplementedFunctionException nie = (NotImplementedFunctionException)e;
|
NotImplementedFunctionException nie = (NotImplementedFunctionException)e;
|
||||||
unsupportedFunctions.add(nie.getFunctionName());
|
unsupportedFunctions.add(nie.getFunctionName());
|
||||||
|
@ -142,16 +142,16 @@ public class CheckFunctionsSupported {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FormulaEvaluationProblems(unsupportedFunctions, unevaluatableCells);
|
return new FormulaEvaluationProblems(unsupportedFunctions, unevaluatableCells);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FormulaEvaluationProblems {
|
public static class FormulaEvaluationProblems {
|
||||||
/** Which used functions are unsupported by POI at this time */
|
/** Which used functions are unsupported by POI at this time */
|
||||||
public Set<String> unsupportedFunctions;
|
private final Set<String> unsupportedFunctions;
|
||||||
/** Which cells had unevaluatable formulas, and why? */
|
/** Which cells had unevaluatable formulas, and why? */
|
||||||
public Map<CellReference,Exception> unevaluatableCells;
|
private final Map<CellReference,Exception> unevaluatableCells;
|
||||||
|
|
||||||
protected FormulaEvaluationProblems(Set<String> unsupportedFunctions,
|
protected FormulaEvaluationProblems(Set<String> unsupportedFunctions,
|
||||||
Map<CellReference, Exception> unevaluatableCells) {
|
Map<CellReference, Exception> unevaluatableCells) {
|
||||||
this.unsupportedFunctions = Collections.unmodifiableSet(unsupportedFunctions);
|
this.unsupportedFunctions = Collections.unmodifiableSet(unsupportedFunctions);
|
||||||
|
|
|
@ -87,17 +87,12 @@ public class ChartFromScratch {
|
||||||
Double[] values1 = listCountries.toArray(new Double[0]);
|
Double[] values1 = listCountries.toArray(new Double[0]);
|
||||||
Double[] values2 = listSpeakers.toArray(new Double[0]);
|
Double[] values2 = listSpeakers.toArray(new Double[0]);
|
||||||
|
|
||||||
try (XWPFDocument doc = new XWPFDocument()) {
|
try (XWPFDocument doc = new XWPFDocument();
|
||||||
|
OutputStream out = new FileOutputStream("chart-from-scratch.docx")) {
|
||||||
XWPFChart chart = doc.createChart(XDDFChart.DEFAULT_WIDTH * 10, XDDFChart.DEFAULT_HEIGHT * 15);
|
XWPFChart chart = doc.createChart(XDDFChart.DEFAULT_WIDTH * 10, XDDFChart.DEFAULT_HEIGHT * 15);
|
||||||
setBarData(chart, chartTitle, series, categories, values1, values2);
|
setBarData(chart, chartTitle, series, categories, values1, values2);
|
||||||
// save the result
|
// save the result
|
||||||
try (OutputStream out = new FileOutputStream("chart-from-scratch.docx")) {
|
doc.write(out);
|
||||||
doc.write(out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Done");
|
System.out.println("Done");
|
||||||
|
|
|
@ -17,11 +17,21 @@
|
||||||
|
|
||||||
package org.apache.poi.util;
|
package org.apache.poi.util;
|
||||||
|
|
||||||
|
import static javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD;
|
||||||
|
import static javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA;
|
||||||
|
import static javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET;
|
||||||
|
import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
|
||||||
|
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||||
|
import static javax.xml.stream.XMLInputFactory.IS_NAMESPACE_AWARE;
|
||||||
|
import static javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES;
|
||||||
|
import static javax.xml.stream.XMLInputFactory.IS_VALIDATING;
|
||||||
|
import static javax.xml.stream.XMLInputFactory.SUPPORT_DTD;
|
||||||
|
import static javax.xml.stream.XMLOutputFactory.IS_REPAIRING_NAMESPACES;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
@ -44,6 +54,8 @@ import org.xml.sax.XMLReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper methods for working with javax.xml classes.
|
* Helper methods for working with javax.xml classes.
|
||||||
|
*
|
||||||
|
* @see <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html">OWASP XXE</a>
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public final class XMLHelper {
|
public final class XMLHelper {
|
||||||
|
@ -86,20 +98,18 @@ public final class XMLHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new DocumentBuilderFactory, with sensible defaults
|
* Creates a new DocumentBuilderFactory, with sensible defaults
|
||||||
*
|
|
||||||
* @see <a href="https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html">OWASP XXE</a>
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"squid:S2755"})
|
@SuppressWarnings({"squid:S2755"})
|
||||||
public static DocumentBuilderFactory getDocumentBuilderFactory() {
|
public static DocumentBuilderFactory getDocumentBuilderFactory() {
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
factory.setNamespaceAware(true);
|
factory.setNamespaceAware(true);
|
||||||
// this doesn't appear to work, and we still need to limit
|
// this doesn't appear to work, and we still need to limit
|
||||||
// entity expansions to 1 in trySetXercesSecurityManager
|
// entity expansions to 1 in trySet(XercesSecurityManager)
|
||||||
factory.setExpandEntityReferences(false);
|
factory.setExpandEntityReferences(false);
|
||||||
factory.setValidating(false);
|
factory.setValidating(false);
|
||||||
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
trySet(factory::setFeature, FEATURE_SECURE_PROCESSING, true);
|
||||||
trySet(factory::setAttribute, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
trySet(factory::setAttribute, ACCESS_EXTERNAL_SCHEMA, "");
|
||||||
trySet(factory::setAttribute, XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
trySet(factory::setAttribute, ACCESS_EXTERNAL_DTD, "");
|
||||||
trySet(factory::setFeature, FEATURE_EXTERNAL_ENTITIES, false);
|
trySet(factory::setFeature, FEATURE_EXTERNAL_ENTITIES, false);
|
||||||
trySet(factory::setFeature, FEATURE_PARAMETER_ENTITIES, false);
|
trySet(factory::setFeature, FEATURE_PARAMETER_ENTITIES, false);
|
||||||
trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
|
trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
|
||||||
|
@ -134,14 +144,16 @@ public final class XMLHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("squid:S2755")
|
||||||
public static SAXParserFactory getSaxParserFactory() {
|
public static SAXParserFactory getSaxParserFactory() {
|
||||||
try {
|
try {
|
||||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||||
factory.setValidating(false);
|
factory.setValidating(false);
|
||||||
factory.setNamespaceAware(true);
|
factory.setNamespaceAware(true);
|
||||||
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
trySet(factory::setFeature, FEATURE_SECURE_PROCESSING, true);
|
||||||
trySet(factory::setFeature, FEATURE_LOAD_DTD_GRAMMAR, false);
|
trySet(factory::setFeature, FEATURE_LOAD_DTD_GRAMMAR, false);
|
||||||
trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
|
trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
|
||||||
|
trySet(factory::setFeature, FEATURE_EXTERNAL_ENTITIES, false);
|
||||||
return factory;
|
return factory;
|
||||||
} catch (RuntimeException | Error re) { // NOSONAR
|
} catch (RuntimeException | Error re) { // NOSONAR
|
||||||
// this also catches NoClassDefFoundError, which may be due to a local class path issue
|
// this also catches NoClassDefFoundError, which may be due to a local class path issue
|
||||||
|
@ -161,7 +173,8 @@ public final class XMLHelper {
|
||||||
public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
|
public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
|
||||||
XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
|
XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
|
||||||
xmlReader.setEntityResolver(XMLHelper::ignoreEntity);
|
xmlReader.setEntityResolver(XMLHelper::ignoreEntity);
|
||||||
trySet(xmlReader::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
trySet(xmlReader::setFeature, FEATURE_SECURE_PROCESSING, true);
|
||||||
|
trySet(xmlReader::setFeature, FEATURE_EXTERNAL_ENTITIES, false);
|
||||||
Object manager = getXercesSecurityManager();
|
Object manager = getXercesSecurityManager();
|
||||||
if (manager == null || !trySet(xmlReader::setProperty, PROPERTY_SECURITY_MANAGER, manager)) {
|
if (manager == null || !trySet(xmlReader::setProperty, PROPERTY_SECURITY_MANAGER, manager)) {
|
||||||
// separate old version of Xerces not found => use the builtin way of setting the property
|
// separate old version of Xerces not found => use the builtin way of setting the property
|
||||||
|
@ -176,10 +189,10 @@ public final class XMLHelper {
|
||||||
@SuppressWarnings({"squid:S2755"})
|
@SuppressWarnings({"squid:S2755"})
|
||||||
public static XMLInputFactory newXMLInputFactory() {
|
public static XMLInputFactory newXMLInputFactory() {
|
||||||
XMLInputFactory factory = XMLInputFactory.newInstance();
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
trySet(factory::setProperty, XMLInputFactory.IS_NAMESPACE_AWARE, true);
|
trySet(factory::setProperty, IS_NAMESPACE_AWARE, true);
|
||||||
trySet(factory::setProperty, XMLInputFactory.IS_VALIDATING, false);
|
trySet(factory::setProperty, IS_VALIDATING, false);
|
||||||
trySet(factory::setProperty, XMLInputFactory.SUPPORT_DTD, false);
|
trySet(factory::setProperty, SUPPORT_DTD, false);
|
||||||
trySet(factory::setProperty, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
trySet(factory::setProperty, IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +201,7 @@ public final class XMLHelper {
|
||||||
*/
|
*/
|
||||||
public static XMLOutputFactory newXMLOutputFactory() {
|
public static XMLOutputFactory newXMLOutputFactory() {
|
||||||
XMLOutputFactory factory = XMLOutputFactory.newInstance();
|
XMLOutputFactory factory = XMLOutputFactory.newInstance();
|
||||||
trySet(factory::setProperty, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
|
trySet(factory::setProperty, IS_REPAIRING_NAMESPACES, true);
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +215,9 @@ public final class XMLHelper {
|
||||||
|
|
||||||
public static TransformerFactory getTransformerFactory() {
|
public static TransformerFactory getTransformerFactory() {
|
||||||
TransformerFactory factory = TransformerFactory.newInstance();
|
TransformerFactory factory = TransformerFactory.newInstance();
|
||||||
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
trySet(factory::setFeature, FEATURE_SECURE_PROCESSING, true);
|
||||||
|
trySet(factory::setAttribute, ACCESS_EXTERNAL_DTD, "");
|
||||||
|
trySet(factory::setAttribute, ACCESS_EXTERNAL_STYLESHEET, "");
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,10 +231,10 @@ public final class XMLHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SchemaFactory getSchemaFactory() {
|
public static SchemaFactory getSchemaFactory() {
|
||||||
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
SchemaFactory factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
|
||||||
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
trySet(factory::setFeature, FEATURE_SECURE_PROCESSING, true);
|
||||||
trySet(factory::setProperty, XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
trySet(factory::setProperty, ACCESS_EXTERNAL_DTD, "");
|
||||||
trySet(factory::setProperty, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
trySet(factory::setProperty, ACCESS_EXTERNAL_SCHEMA, "");
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.OutputKeys;
|
import javax.xml.transform.OutputKeys;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
|
||||||
|
@ -83,7 +82,7 @@ public class WordToTextConverter extends AbstractWordConverter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java main() interface to interact with {@link WordToTextConverter}
|
* Java main() interface to interact with {@link WordToTextConverter}
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Usage: WordToTextConverter infile outfile
|
* Usage: WordToTextConverter infile outfile
|
||||||
* </p>
|
* </p>
|
||||||
|
@ -131,7 +130,7 @@ public class WordToTextConverter extends AbstractWordConverter
|
||||||
/**
|
/**
|
||||||
* Creates new instance of {@link WordToTextConverter}. Can be used for
|
* Creates new instance of {@link WordToTextConverter}. Can be used for
|
||||||
* output several {@link HWPFDocument}s into single text document.
|
* output several {@link HWPFDocument}s into single text document.
|
||||||
*
|
*
|
||||||
* @throws ParserConfigurationException
|
* @throws ParserConfigurationException
|
||||||
* if an internal {@link DocumentBuilder} cannot be created
|
* if an internal {@link DocumentBuilder} cannot be created
|
||||||
*/
|
*/
|
||||||
|
@ -144,7 +143,7 @@ public class WordToTextConverter extends AbstractWordConverter
|
||||||
/**
|
/**
|
||||||
* Creates new instance of {@link WordToTextConverter}. Can be used for
|
* Creates new instance of {@link WordToTextConverter}. Can be used for
|
||||||
* output several {@link HWPFDocument}s into single text document.
|
* output several {@link HWPFDocument}s into single text document.
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* XML DOM Document used as storage for text pieces
|
* XML DOM Document used as storage for text pieces
|
||||||
*/
|
*/
|
||||||
|
@ -178,11 +177,8 @@ public class WordToTextConverter extends AbstractWordConverter
|
||||||
DOMSource domSource = new DOMSource( getDocument() );
|
DOMSource domSource = new DOMSource( getDocument() );
|
||||||
StreamResult streamResult = new StreamResult( stringWriter );
|
StreamResult streamResult = new StreamResult( stringWriter );
|
||||||
|
|
||||||
TransformerFactory tf = TransformerFactory.newInstance();
|
Transformer serializer = XMLHelper.newTransformer();
|
||||||
Transformer serializer = tf.newTransformer();
|
|
||||||
// TODO set encoding from a command argument
|
// TODO set encoding from a command argument
|
||||||
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
|
|
||||||
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
|
|
||||||
serializer.setOutputProperty( OutputKeys.METHOD, "text" );
|
serializer.setOutputProperty( OutputKeys.METHOD, "text" );
|
||||||
serializer.transform( domSource, streamResult );
|
serializer.transform( domSource, streamResult );
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.xml.transform.OutputKeys;
|
import javax.xml.transform.OutputKeys;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
|
||||||
|
@ -106,10 +105,7 @@ public class TestExcelConverterSuite
|
||||||
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
|
||||||
Transformer transformer = TransformerFactory.newInstance()
|
Transformer transformer = XMLHelper.newTransformer();
|
||||||
.newTransformer();
|
|
||||||
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
|
|
||||||
transformer.setOutputProperty( OutputKeys.INDENT, "no" );
|
|
||||||
transformer.setOutputProperty( OutputKeys.METHOD, "html" );
|
transformer.setOutputProperty( OutputKeys.METHOD, "html" );
|
||||||
transformer.transform(
|
transformer.transform(
|
||||||
new DOMSource( excelToHtmlConverter.getDocument() ),
|
new DOMSource( excelToHtmlConverter.getDocument() ),
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.xml.transform.OutputKeys;
|
import javax.xml.transform.OutputKeys;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
|
||||||
|
@ -105,10 +104,7 @@ public class TestWordToConverterSuite
|
||||||
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
|
||||||
Transformer transformer = TransformerFactory.newInstance()
|
Transformer transformer = XMLHelper.newTransformer();
|
||||||
.newTransformer();
|
|
||||||
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
|
|
||||||
transformer.setOutputProperty( OutputKeys.INDENT, "false" );
|
|
||||||
transformer.setOutputProperty( OutputKeys.METHOD, "html" );
|
transformer.setOutputProperty( OutputKeys.METHOD, "html" );
|
||||||
transformer.transform(
|
transformer.transform(
|
||||||
new DOMSource( wordToHtmlConverter.getDocument() ),
|
new DOMSource( wordToHtmlConverter.getDocument() ),
|
||||||
|
@ -134,9 +130,7 @@ public class TestWordToConverterSuite
|
||||||
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
|
||||||
Transformer transformer = TransformerFactory.newInstance()
|
Transformer transformer = XMLHelper.newTransformer();
|
||||||
.newTransformer();
|
|
||||||
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
|
|
||||||
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
|
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
|
||||||
transformer.setOutputProperty( OutputKeys.METHOD, "text" );
|
transformer.setOutputProperty( OutputKeys.METHOD, "text" );
|
||||||
transformer.transform(
|
transformer.transform(
|
||||||
|
|
Loading…
Reference in New Issue