How do I export charts from Excel as graphics - java

I've got a series of Excel spreadsheets, each with at least one page of data and one page of a chart created from the data. I need to capture ( not regenerate from the data ) the existing chart as a web friendly image. Is this possible via Java or .Net? I know the POI stuff (Java) won't do it (or so I'm told, haven't tried it myself).

Have you tried using the Chart.Export Method?
The example in help is:
Worksheets("Sheet1").ChartObjects(1).Chart. Export _
FileName:="current_sales.gif", FilterName:="GIF"
From memory, I think you can export to PNG as well.

Chart images are not stored in workbooks, so you need a component which can render Excel compatible charts.
SpreadsheetGear for .NET will let you load Excel workbooks, optionally plug in new values / formulas / formats / etc..., calculate, and then get an image from a range of cells or from a chart.
You can see some samples here and download the free trial here if you want to try it yourself.
Disclaimer: I own SpreadsheetGear LLC

You can convert or copy charts(graphs) using J XL or Aspose Cells(Aspose is not free).
This is the code snippet to extract excel chart to image
public class ExportChartToImage
{
public static void main(String[] args) throws Exception
{
//Start Excel
Application excelApp = new Application();
excelApp.setVisible(true);
//Create test workbook
Workbook workbook = excelApp.createWorkbook("/home/tejus/Desktop/Chart Test");
//Get the first (and the only) worksheet
final Worksheet worksheet1 = workbook.getWorksheet(1);
//Fill-in the first worksheet with sample data
worksheet1.getCell("A1").setValue("Date");
worksheet1.getCell("A2").setValue("March 1");
worksheet1.getCell("A3").setValue("March 8");
worksheet1.getCell("A4").setValue("March 15");
worksheet1.getCell("B1").setValue("Customer");
worksheet1.getCell("B2").setValue("Smith");
worksheet1.getCell("B3").setValue("Jones");
worksheet1.getCell("B4").setValue("James");
worksheet1.getCell("C1").setValue("Sales");
worksheet1.getCell("C2").setValue("23");
worksheet1.getCell("C3").setValue("17");
worksheet1.getCell("C4").setValue("39");
excelApp.getOleMessageLoop().doInvokeAndWait(new Runnable()
{
public void run()
{
final Variant unspecified = Variant.createUnspecifiedParameter();
final Int32 localeID = new Int32(LocaleID.LOCALE_SYSTEM_DEFAULT);
Range sourceDataNativePeer = worksheet1.getRange("A1:C4").getPeer();
_Worksheet worksheetNativePeer = worksheet1.getPeer();
IDispatch chartObjectDispatch = worksheetNativePeer.chartObjects(unspecified, localeID);
ChartObjectsImpl chartObjects = new ChartObjectsImpl(chartObjectDispatch);
ChartObject chartObject = chartObjects.add(new DoubleFloat(100), new DoubleFloat(150), new DoubleFloat(300), new DoubleFloat(225));
_Chart chart = chartObject.getChart();
chart.setSourceData(sourceDataNativePeer, new Variant(XlRowCol.xlRows));
BStr fileName = new BStr("/home/tejus/Desktop/chart.gif");
Variant filterName = new Variant("gif");
Variant interactive = new Variant(false);
chart.export(fileName, filterName, interactive);
chart.setAutoDelete(false);
chart.release();
chartObject.setAutoDelete(false);
chartObject.release();
chartObjects.setAutoDelete(false);
chartObjects.release();
chartObjectDispatch.setAutoDelete(false);
chartObjectDispatch.release();
}
});
System.out.println("Press 'Enter' to terminate the application");
System.in.read();
//Close the MS Excel application.
boolean saveChanges = false;
workbook.close(saveChanges);
boolean forceQuit = true;
excelApp.close(forceQuit);
}
}
i used J excel

Related

iText 2D barcode not recognized by scanner

I have a java Swing application which generates barcode labels to be printed on Soho stickers. The stickers are then put on actual items, in my case it is books.
I have followed steps for generating 2D barcodes as describe in the book "iText in Action, 2nd Edition" page 334. I generate the barcodes in a PDF document and print, but it is the scanning that does not work. My scanner is E-POS, model EC301 and can scan other barcode labels very quickly. My code is as shown below:
private PdfPCell createBarcode(String code) throws DocumentException, IOException {
BarcodeEAN barcode = new BarcodeEAN();
barcode.setCodeType(Barcode.EAN13);
barcode.setCode(code);
PdfPCell cell = new PdfPCell(barcode.createImageWithBarcode(writer.getDirectContent(), BaseColor.BLACK, BaseColor.GRAY), true);
cell.setBorderWidth(0.1f);
cell.setPadding(10);
return cell;
}
To create a barcode, i call the function like this:
createBarcode(String.format("%013d", 1));
Where could I possibly be wrong?

Apache POI Java - Docx Charts and Graphs

Iv been working with XWPF documents for several weeks now and I have not been able to add charts. Pie charts, Bar charts. I plan to manually inject a chart with XML into the file but i think its excessive. I just want to add a chart to a Docx template. Aspose and javadocx are not options.
XWPFDocument document = new XWPFDocument(getClass().getResourceAsStream("/templates/standard.docx"));
//INSERT PIE CHART
FileOutputStream out = new FileOutputStream(new File("output/output.docx");
document.write(out);
[UPDATE - The Easy Route]
Due to time it would take to successfully write an injection method, iv found a handy (Quick n dirty) way of adding charts. This is not the normal word charts but one generated from a library, stored as a picture and inserted.
First, i downloaded the library from http://knowm.org/open-source/xchart/xchart-example-code.
Second, one you have implemented your XWPFdocument, you create a chart and append it as an image.
private XWPFDocument add_chart(XWPFDocument document)
{
// New Chart Element
CategoryChart chart = new CategoryChartBuilder().width(500).height(400).theme(Styler.ChartTheme.GGPlot2).title(getClass().getSimpleName()).build();
chart.setTitle("Issue Count");
// Customize Chart
Color[] sliceColors = new Color[]{new Color(27, 50, 119), new Color(58, 146, 56), new Color(0, 161, 222), new Color(154, 205, 102), new Color(246, 199, 182)};
chart.getStyler().setSeriesColors(sliceColors);
// Series
chart.addSeries("Critical", new ArrayList<>(Arrays.asList(new String[]{"Count"})), new ArrayList<>(Arrays.asList(new Number[]{10})));
chart.addSeries("High", new ArrayList<>(Arrays.asList(new String[]{"High"})), new ArrayList<>(Arrays.asList(new Number[]{5})));
chart.addSeries("Medium", new ArrayList<>(Arrays.asList(new String[]{"Medium"})), new ArrayList<>(Arrays.asList(new Number[]{2})));
chart.addSeries("Low", new ArrayList<>(Arrays.asList(new String[]{"Low"})), new ArrayList<>(Arrays.asList(new Number[]{1})));
// Create and store a jpg image of the chart, then append it to the document
BitmapEncoder.saveBitmapWithDPI(chart, "tmp.jpg", BitmapFormat.JPG, 300);
document.createParagraph().createRun().addPicture(new FileInputStream("tmp.jpg"), XWPFDocument.PICTURE_TYPE_JPEG, "tmp.jpg", Units.toEMU(500), Units.toEMU(400));
return document;
}
An example of one chart i made using the library:
You can use below location's customise poi jar to read and modify chart of document file and then write into your actual document file.
using XWPFChart class you can use all method as we have available for POI EXCEL/PPT.
https://github.com/sandeeptiwari32/POI_ENHN/POI3.14.jar
below is simple example to read chart from MS-WORD File
public class PoiDocTest {
public static void main(String arg[]) throws FileNotFoundException, IOException
{
#SuppressWarnings("resource")
XWPFDocument document = new XWPFDocument(new FileInputStream("chart.docx"));
#SuppressWarnings("unused")
XWPFChart chart;
for (POIXMLDocumentPart part : document.getRelations()) {
if (part instanceof XWPFChart) {
chart = (XWPFChart) part;
break;
}
}
}
}

LibGDX - How to save generated FreeType fonts

I have problem with fonts lin LibGDX. I have three different fonts and parameters:
parameter_score = new FreeTypeFontGenerator.FreeTypeFontParameter();
//Some parameters..
font_score = generator.generateFont(parameter_score);
parameter_Big = new FreeTypeFontGenerator.FreeTypeFontParameter();
//Some parameters..
font_Big = generator.generateFont(parameter_Big);
parameter_Small = new FreeTypeFontGenerator.FreeTypeFontParameter();
//Some parameters..
font_Small = generator.generateFont(parameter_Small);
and it is very slow to generate fonts. When the app starts, i see black screen for about 3 seconds. I heard about method, when I generate fonts only first time, then I save it to some file, and when I lunch app next time, it will get generated fonts from file. But i dont know how to save, and load generated fonts. Do anyone know?
BitmapFontWriter
BitmapFontWriter is a class in gdx-tools which can write BMFont files from a BitmapFontData instance. This allows a font to be generated using FreeTypeFontGenerator, then written to a font file and PNG files. BitmapFontWriter has the benefit that it can be more easily run from scripts and can make use of FreeTypeFontGenerator's shadows and borders. Otherwise, the output is very similar to Hiero, though Hiero avoids writing a glyph image multiple times if different character codes render the same glyph.
Usage can look like this:
new LwjglApplication(new ApplicationAdapter() {
public void create () {
FontInfo info = new FontInfo();
info.padding = new Padding(1, 1, 1, 1);
FreeTypeFontParameter param = new FreeTypeFontParameter();
param.size = 13;
param.gamma = 2f;
param.shadowOffsetY = 1;
param.renderCount = 3;
param.shadowColor = new Color(0, 0, 0, 0.45f);
param.characters = Hiero.EXTENDED_CHARS;
param.packer = new PixmapPacker(512, 512, Format.RGBA8888, 2, false, new SkylineStrategy());
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.absolute("some-font.ttf"));
FreeTypeBitmapFontData data = generator.generateData(param);
BitmapFontWriter.writeFont(data, new String[] {"font.png"},
Gdx.files.absolute("font.fnt"), info, 512, 512);
BitmapFontWriter.writePixmaps(param.packer.getPages(), Gdx.files.absolute("imageDir"), name);
System.exit(0);
}
});
https://github.com/libgdx/libgdx/wiki/Hiero#bitmapfontwriter

Reading a table or cell value in a pdf file using java?

I have gone through Java and PDF forums to extract a text value from the table in a pdf file, but could't find any solution except JPedal (It's not opensource and licensed).
So, I would like to know any opensource API's like pdfbox, itext to achieve the same result as JPedal.
Ref. Example:
In comments the OP clarified that he locates the text value from the table in a pdf file he wants to extract
By providing X and Y co-ordinates
Thus, while the question initially sounded like generic extraction of tabular data from PDFs (which can be difficult at least), it actually is essentially about extracting the text from a rectangular region on a page given by coordinates.
This is possible using either of the libraries you mentioned (and surely others, too).
iText
To restrict the region from which you want to extract text, you can use the RegionTextRenderFilter in a FilteredTextRenderListener, e.g.:
/**
* Parses a specific area of a PDF to a plain text file.
* #param pdf the original PDF
* #param txt the resulting text
* #throws IOException
*/
public void parsePdf(String pdf, String txt) throws IOException {
PdfReader reader = new PdfReader(pdf);
PrintWriter out = new PrintWriter(new FileOutputStream(txt));
Rectangle rect = new Rectangle(70, 80, 490, 580);
RenderFilter filter = new RegionTextRenderFilter(rect);
TextExtractionStrategy strategy;
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), filter);
out.println(PdfTextExtractor.getTextFromPage(reader, i, strategy));
}
out.flush();
out.close();
reader.close();
}
(ExtractPageContentArea sample from iText in Action, 2nd edition)
Beware, though, iText extracts text based on the basic text chunks in the content stream, not based on each individual glyph in such a chunk. Thus, the whole chunk is processed if only the tiniest part of it is in the area.
This may or may not suit you.
If you run into the problem that more is extracted than you wanted, you should split the chunks into their constituting glyphs beforehand. This stackoverflow answer explains how to do that.
PDFBox
To restrict the region from which you want to extract text, you can use the PDFTextStripperByArea, e.g.:
PDDocument document = PDDocument.load( args[0] );
if( document.isEncrypted() )
{
document.decrypt( "" );
}
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
stripper.setSortByPosition( true );
Rectangle rect = new Rectangle( 10, 280, 275, 60 );
stripper.addRegion( "class1", rect );
List allPages = document.getDocumentCatalog().getAllPages();
PDPage firstPage = (PDPage)allPages.get( 0 );
stripper.extractRegions( firstPage );
System.out.println( "Text in the area:" + rect );
System.out.println( stripper.getTextForRegion( "class1" ) );
(ExtractTextByArea from the PDFBox 1.8.8 examples)
Try PDFTextStream. At least I am able to identify the column values. Earlier, I was using iText and got stuck in defining strategy. Its hard.
This api separates column cells by putting more spaces. Its fixed. you can put logic. (this was missing in iText).
import com.snowtide.PDF;
import com.snowtide.pdf.Document;
import com.snowtide.pdf.OutputTarget;
public class PDFText {
public static void main(String[] args) throws java.io.IOException {
String pdfFilePath = "xyz.pdf";
Document pdf = PDF.open(pdfFilePath);
StringBuilder text = new StringBuilder(1024);
pdf.pipe(new OutputTarget(text));
pdf.close();
System.out.println(text);
}
}
Question has been asked related to this on stackoverflow!

Create Excel Chart within Excel File

I am exporting some data from my system. I want to visualize these datasets in an excel chart. I have found and old, closed question, where the solution was missing. The charts should redraw when i change a datafield, this is excel standard, i guess.
I think it may work this way:
export Data
create manually a chart with MS-Excel
save and load this as a template in all other future exports
Do you know how to do it with POI using Java? Especially the import of the chart as template?
POI doesn't give you that functionality but You can convert or copy charts(graphs) using J XL or Aspose Cells(Aspose is not free).
This is the code snippet to extract excel chart to image
public class ExportChartToImage
{
public static void main(String[] args) throws Exception
{
//Start Excel
Application excelApp = new Application();
excelApp.setVisible(true);
//Create test workbook
Workbook workbook = excelApp.createWorkbook("/home/tejus/Desktop/Chart Test");
//Get the first (and the only) worksheet
final Worksheet worksheet1 = workbook.getWorksheet(1);
//Fill-in the first worksheet with sample data
worksheet1.getCell("A1").setValue("Date");
worksheet1.getCell("A2").setValue("March 1");
worksheet1.getCell("A3").setValue("March 8");
worksheet1.getCell("A4").setValue("March 15");
worksheet1.getCell("B1").setValue("Customer");
worksheet1.getCell("B2").setValue("Smith");
worksheet1.getCell("B3").setValue("Jones");
worksheet1.getCell("B4").setValue("James");
worksheet1.getCell("C1").setValue("Sales");
worksheet1.getCell("C2").setValue("23");
worksheet1.getCell("C3").setValue("17");
worksheet1.getCell("C4").setValue("39");
excelApp.getOleMessageLoop().doInvokeAndWait(new Runnable()
{
public void run()
{
final Variant unspecified = Variant.createUnspecifiedParameter();
final Int32 localeID = new Int32(LocaleID.LOCALE_SYSTEM_DEFAULT);
Range sourceDataNativePeer = worksheet1.getRange("A1:C4").getPeer();
_Worksheet worksheetNativePeer = worksheet1.getPeer();
IDispatch chartObjectDispatch = worksheetNativePeer.chartObjects(unspecified, localeID);
ChartObjectsImpl chartObjects = new ChartObjectsImpl(chartObjectDispatch);
ChartObject chartObject = chartObjects.add(new DoubleFloat(100), new DoubleFloat(150), new DoubleFloat(300), new DoubleFloat(225));
_Chart chart = chartObject.getChart();
chart.setSourceData(sourceDataNativePeer, new Variant(XlRowCol.xlRows));
BStr fileName = new BStr("/home/tejus/Desktop/chart.gif");
Variant filterName = new Variant("gif");
Variant interactive = new Variant(false);
chart.export(fileName, filterName, interactive);
chart.setAutoDelete(false);
chart.release();
chartObject.setAutoDelete(false);
chartObject.release();
chartObjects.setAutoDelete(false);
chartObjects.release();
chartObjectDispatch.setAutoDelete(false);
chartObjectDispatch.release();
}
});
System.out.println("Press 'Enter' to terminate the application");
System.in.read();
//Close the MS Excel application.
boolean saveChanges = false;
workbook.close(saveChanges);
boolean forceQuit = true;
excelApp.close(forceQuit);
}
}
i used J excel
Till now as the apache POI limitation is saying "You can not currently create charts. You can however create a chart in Excel, modify the chart data values using HSSF and write a new spreadsheet out. This is possible because POI attempts to keep existing records intact as far as possible".
However in my case, I have created a chart manually on excel sheet using Named Ranges, and using java, I am updating named ranges as per my requirement. Since the chart is based on named ranges so it also get updated.
For updation please check here

Categories

Resources