‫خواندن و نوشتن فایل های Excel در داخل جاوا با استفاده از کتابخانه ی معروف Apache POI

Apache-POI

‫امروز با یک آموزش دیگر در خدمتتان هستیم!  در این آموزش به کتابخانه Apache POI میپردازیم که بوسیله آن میتوان فایل های متنوع Word ، Excel و Power Point  را تولید کرد.

پیشگفتار

‫‫‫کتابخانه ی Apache POI یک کتابخانه همه کاره برای تغییر فرمت های استاندارده Office Open XML ‫‫(OOXML) و Microsoft OLE 2 Compound Document یا OLE2 می باشد.

‫‫این کتابخانه به شما امکان خواندن و نوشتن روی داکیومنت های word ، powerpoint و ورژن  های ۹۷ تا ۲۰۰۸ عه فرمت Excel رو میدهد. اکثر فایل های آفیس مایکروسافت توسط OLE2 پشتیبانی میشوند، مثل فرمت های‫ ‫XLS، DOC، PPT و MFC Serialization . این پروژه به شما API ی را برای OLE Filesystem یا POIFS و OLE Document Properties یا HPSF را ارائه میکند.
‫فرمت Office OpenXML استاندارد جدیدی می باشد که شمایل XML ی دارد و در Microsoft Office 2007 و 2008 یافت میشود. فرمت های XLSX و DOCX و PPTX از نوع این فرمت ها می باشند. کتابخانه Apache POI با استفاده از کتابخانه (openxml4j) یه API عه لایه ی پایین به شما ارايه میکند که میتوانید این فرمت هارو هم استفاده کنید.

‫برای فرمت های MS Office ماژولی وجود دارد که تلاش میکند که یه Java API عه سطح بالا ارائه کند که هم فرمت های OLE2 و هم OOXML را بخواند و بنویسد. در داخل کتابخانه ی POI این مهم، برای فایل های اکسلیه HSSF و XSSF که بهشون SS گفته میشود

(SS=HSSF+XSSF)

‫خیلی خوب توسعه داده شده است و برای داکیومنت های   wordو powerpoint در حال توسعه می باشد.  این فرمت ها:

Word documents (WP=HWPF+XWPF) and PowerPoint presentations (SL=HSLF+XSLF)

‫‫‫‫ این پروژه یکسری بخشم برای  Outlook HSMF فایل های ویزیو XDGF-HDGF و -NEF HMEF و publisher-HPBF را دارا می باشد.

‫چرا باید از Apache POI استفاده کنیم

‫بیشترین استفاده ی این کتابخانه در استخراج متن می باشد مثلا web spider ها  مثل crawler های موتورهای جستجو، index builder ها و سیستم های مدیریت محتوا میتوانند از این کتابخانه استفاده کنند.

‫حال سوال اینجاس که چرا باید از POIFS و HSSF وXSSF استفاده کنیم؟ (معنی هرکدام در پیشگفتار شرح داده شده است)

‫- برای نوشتن و خواندن فرمت های ترکیبی داکیومنت های استاندارد OLE2 باید از POIFS استفاده شود. در حال حاضر POIFS کاملترین کتابخانه برای این کار در جهان است
‫-‫ برای نوشتن و خواندن فایل های اکسلی XLS باید از XSSF برای خواندن و OOXML برای نوشتن استفاده میشود (فایل XLSX). ترکیب این دو که SS نامیده می شود به شما این امکان را میدهد که هر فایل Excel ی را بتوانید بخوانید و بنویسید.

‫پیاده سازی SXSSF ی در داخل این کتابخانه نیز وجود دارد که به شما این امکان را میدهد که فایل های اکسل خیلی خیلی بزرگ را به حالت بهینه بخوانید و در حافظه بارگزاری کنید

‫برای نوشتن کد برنامه ی Excel شما باید ابتدا کتابخانه های maven ی آن را اضافه کنید. 

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.1</version>
</dependency>

‫بعد از اضافه کردن کتابخانه ها میتوانید شروع به نوشتن برنامه شوید.

مثال نوشتن یک فایل اکسل مایکروسافتی

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class ExcelWriting {

    public static final String DESKTOP_PATH = String.format("%s%s%s%s", System.getProperty("user.home"), File.separator, "Desktop", File.separator);


    public static void writeExcel(List<User> users, String filename) throws IOException {

        //یه ورک بوک برای شما درست میکنه
        Workbook wb = null;
        OutputStream os = null;
        try {
            wb = new HSSFWorkbook();

            // پر کردن محتوای اکسل
            wb = createContent(wb, users);

            // آماده سازی stream برای نوشتن روی فایل
            os = new FileOutputStream(new File(DESKTOP_PATH + filename + ".xlsx"));

            // نوشتن بر روی فایلا
            wb.write(os);
        } finally {
            if (wb != null)
                wb.close();

            if (os != null)
                os.close();
        }


    }

    private static Workbook createContent(Workbook wb, List<User> users) {
        if (wb == null)
            throw new IllegalArgumentException("Data is missing");

        // صفحه ی Excel با نام top-sheet
        Sheet mainSheet = wb.createSheet("top-sheet");

        //درست کردن سرفصله صفحه
        String[] heading = {"First Name", "Last Name", "Username", "Email Address"};
        Row headingRow = mainSheet.createRow(0);
        for (int i = 0; i < heading.length; i++) {
            Cell cell = headingRow.createCell(i);
            cell.setCellValue(heading[i]);

            //اضافه کردن استایل برای هدینگ صفحه
            CellStyle cs = wb.createCellStyle();

            Font font = wb.createFont();
            font.setBold(true);
            font.setColor(HSSFColor.HSSFColorPredefined.DARK_RED.getIndex());

            cs.setAlignment(HorizontalAlignment.CENTER);
            cs.setFont(font);

            cell.setCellStyle(cs);
        }

        //درست کردن محتوای فایل Excel
        for (int row = 0; row < users.size(); row++) {
            Row contentRow = mainSheet.createRow((row + 1));//چون سطر اول هدینگ صفحه هستش و باید از سطر بعدی شروع کنیم
            User user = users.get(row);

            //برای راحت حلقه زدن روی ستون ها بهتره به این شکل درش بیاریم ابتدا
            String[] contents = {user.getFirstName(), user.getLastName(), user.getUsername(), user.getEmailAddress()};
            for (int col = 0; col < contents.length; col++) {
                Cell cell = contentRow.createCell(col);
                cell.setCellValue(contents[col]);
            }
        }

        return wb;
    }

    private static List<User> dummyUsers(final int num) {
        final List<User> users = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            users.add(new User(randStr(5), randStr(8), randStr(6), String.format("%s@%s.%s", randStr(5), randStr(5), randStr(3))));
        }

        return users;
    }

    private static String randStr(int length) {
        return UUID.randomUUID().toString().substring(0, length);
    }

    public static void main(String[] args) throws IOException {
        List<User> users = dummyUsers(1000);
        writeExcel(users, "iropensource");

    }
}

final class User {
    private String firstName;
    private String lastName;
    private String username;
    private String emailAddress;

    public User(String firstName, String lastName, String username, String emailAddress) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.username = username;
        this.emailAddress = emailAddress;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getUsername() {
        return username;
    }

    public String getEmailAddress() {
        return emailAddress;
    }
}

‫نمایی از خروجی فایل نوشته شده در نرم افزار LibreOffice

xls-written-file-look

مثال خواندن یک فایل اکسل مایکروسافتی

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ExcelReading {

    public static final String DESKTOP_PATH = String.format("%s%s%s%s", System.getProperty("user.home"), File.separator, "Desktop", File.separator);


    public static List<User> readExcel(String fileName) throws IOException, InvalidFormatException {
        List<User> users = new ArrayList<>();

        Workbook wb = null;
        InputStream is = null;
        try {
            is = new FileInputStream(new File(DESKTOP_PATH + fileName + ".xlsx"));
            wb = new HSSFWorkbook(is);

            // صفحه اکسل رو بگیر
            Sheet sheet = wb.getSheet("top-sheet");

            // برای استفاده حلقه یه iterator بگیر
            Iterator<Row> iterator = sheet.iterator();

            //چون ردیف اول مرتبطه با هدینگ دیتا و ما میخواهیم آبجکت یوزر رو پر کنیم از این ردیف صرف نظر میکنیم
            // این کد مکان نمای حلقه رو یدونه میندازه جلو یعنی سطر اول هدینگ توی حلقه ی پایین دیگه نیست
            Row currentRow = iterator.next();

            // مادامی که سطری وجود دارد تکرار شو
            while (iterator.hasNext()) {
                // سطر جاری
                currentRow = iterator.next();

                // برای استفاده حلقه روی ستون ها
                Iterator<Cell> cellIterator = currentRow.iterator();


                String firstName = null, lastName = null, username = null, emailAddress = null;
                // مادامی که ستونی وجود دارد تکرار شو
                while (cellIterator.hasNext()) {

                    //ستونه جاری
                    Cell currentCell = cellIterator.next();

                    //مقدار ستون جاری
                    String value = currentCell.getStringCellValue();

                    // طبق ایندکس تون میفهمیم که هرکدام برای چه مقداریه
                    switch (currentCell.getColumnIndex()) {
                        case 0:
                            firstName = value;
                            break;
                        case 1:
                            lastName = value;
                            break;
                        case 2:
                            username = value;
                            break;
                        case 3:
                            emailAddress = value;
                            break;
                    }
                }

                // آبجکت ستون مورد نظر را می سازیم
                User rowUser = new User(firstName, lastName, username, emailAddress);

                //آبجکت رو اضافه میکنیم
                users.add(rowUser);

            }


        } finally {
            if (wb != null)
                wb.close();

            if (is != null)
                is.close();
        }


        return users;
    }

    public static void main(String[] args) throws IOException, InvalidFormatException {
        List<User> users = readExcel("iropensource");

        //نمایش ۱۰ تای اول اگر لیست بزرگتر از ۱۰ تا بود
        int length = users.size() <= 10 ? users.size() : 10;

        for (int i = 0; i < length; i++) {
            System.out.println(users.get(i));
        }

    }
}

final class User {
    private String firstName;
    private String lastName;
    private String username;
    private String emailAddress;

    public User(String firstName, String lastName, String username, String emailAddress) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.username = username;
        this.emailAddress = emailAddress;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getUsername() {
        return username;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    @Override
    public String toString() {
        return String.format("First Name: %s | Last Name: %s | Username: %s | Email Address: %s", firstName, lastName, username, emailAddress);
    }
}

‫نمایی از خروجی ۱۰ سطر اول خوانده شده :

First Name: 2dba2 | Last Name: a63b90ee | Username: a4b678 | Email Address: 54b47@9c4d3.c9b
First Name: feac8 | Last Name: 8985d1af | Username: 06c5e4 | Email Address: 1c393@8bb50.a63
First Name: 1931f | Last Name: 3b32af06 | Username: 60ed59 | Email Address: cfac0@ff8e2.636
First Name: a189b | Last Name: b777cc91 | Username: de9650 | Email Address: 4e36c@3914b.9a7
First Name: 950f5 | Last Name: 00be7e37 | Username: a9d46e | Email Address: 74d1a@95858.14f
First Name: 8b4a0 | Last Name: 4e6301d6 | Username: b2d79b | Email Address: 8720e@50ba1.9fb
First Name: da0ca | Last Name: c692867f | Username: 6ca100 | Email Address: be1ad@b5102.8f9
First Name: 5f845 | Last Name: 7ee9e987 | Username: 2b162c | Email Address: 33a34@993d6.c11
First Name: 63c2d | Last Name: 355ecfd5 | Username: a60792 | Email Address: beb0b@3e88d.350
First Name: fa418 | Last Name: 59eddb9f | Username: b04a4f | Email Address: 4985d@1ab8b.106

 

دانلود کل پروژه

Published by

mehdi

I'm a Passionate Software Developer and Team Leader