Создание pdf файла в андроиде программно и запись в него

Я пытаюсь создать файл PDF внутри своего приложения, сохранить его во внешнем хранилище и открыть. Для меня не проблема сохранить файл и открыть его, моя проблема связана с его созданием и записью в него. Итак, после некоторых исследований в Интернете я нашел следующий способ сделать это:

        File file = new File(directoryName, fileName);

        // Creating output stream to write in the newly created file
        FileOutputStream fOut = null;

        try {
            fOut = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        // Creating a new document
        Document document = new Document(PageSize.A4, 50, 50, 50, 50);

        try {
            PdfWriter.getInstance(document, fOut);

            // Open the document for writing
            document.open();

            // Write in the document
            document.add(new Paragraph("Hello world"));
            document.close();

        } catch(DocumentException de) {
            System.err.println(de.getMessage());
        }

После запуска моего приложения и выполнения приведенного выше кода я получаю следующую ошибку:

java.lang.NoClassDefFoundError: Failed resolution of: Ljava/awt/Color;

Кто-нибудь знает, в чем проблема с моим кодом или другим способом, который обязательно сработает для создания и записи файла PDF?

Спасибо !


person Husayn Hakeem    schedule 15.12.2015    source источник
comment
Кто-нибудь знает, в чем проблема с моим кодом - вы используете библиотеку, которая не поддерживает Android. В Android нет java.awt.Color.   -  person CommonsWare    schedule 15.12.2015
comment
О, так что в основном я использую код, который несовместим с Android. Спасибо!   -  person Husayn Hakeem    schedule 15.12.2015
comment
Проверьте эту ссылку: sourceforge.net/projects/apwlibrary он способен создавать PDF-файлы на Android и вы можете использовать его под лицензией BSD — я создал простые PDF-файлы на Android с текстом и изображениями и работает нормально — стоит посмотреть.   -  person Mark Keen    schedule 15.12.2015
comment
@MarkKeen Большое спасибо!   -  person Husayn Hakeem    schedule 15.12.2015
comment
Похоже, вы используете стандартную версию iText. На Android вместо этого следует использовать специальную версию iTextG (для GAE и Android). droidText (о котором вы упоминаете в своем ответе) на самом деле является побочным продуктом старой версии iText.   -  person mkl    schedule 16.12.2015


Ответы (4)


Таким образом, код, который я использовал, не был совместим с Android, поэтому я получал ошибку. Ниже вы найдете правильный код, который действительно работает правильно (для создания pdf-файла, добавления в него некоторого содержимого, сохранения и открытия вновь созданного файла):

PS: для этого вам нужно добавить jar iTextG в свой проект:

// Method for creating a pdf file from text, saving it then opening it for display
    public void createandDisplayPdf(String text) {

        Document doc = new Document();

        try {
            String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Dir";

            File dir = new File(path);
            if(!dir.exists())
                dir.mkdirs();

            File file = new File(dir, "newFile.pdf");
            FileOutputStream fOut = new FileOutputStream(file);

            PdfWriter.getInstance(doc, fOut);

            //open the document
            doc.open();

            Paragraph p1 = new Paragraph(text);
            Font paraFont= new Font(Font.COURIER);
            p1.setAlignment(Paragraph.ALIGN_CENTER);
            p1.setFont(paraFont);

            //add paragraph to document
            doc.add(p1);    

        } catch (DocumentException de) {
            Log.e("PDFCreator", "DocumentException:" + de);
        } catch (IOException e) {
            Log.e("PDFCreator", "ioException:" + e);
        }
        finally {
            doc.close();
        }

        viewPdf("newFile.pdf", "Dir");
    }

    // Method for opening a pdf file
    private void viewPdf(String file, String directory) {

        File pdfFile = new File(Environment.getExternalStorageDirectory() + "/" + directory + "/" + file);
        Uri path = Uri.fromFile(pdfFile);

        // Setting the intent for pdf reader
        Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
        pdfIntent.setDataAndType(path, "application/pdf");
        pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        try {
            startActivity(pdfIntent);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(TableActivity.this, "Can't read pdf file", Toast.LENGTH_SHORT).show();
        }
    }
person Husayn Hakeem    schedule 15.12.2015
comment
Я обновил ваш ответ. Пожалуйста, не продвигайте DroidText. DroidText основан на версии iText, выпущенной в 2009 году и имеющей известные технические и юридические проблемы. Вам следует избегать его использования. Это не одобрено владельцами интеллектуальной собственности iText; это никак не поддерживается. - person Bruno Lowagie; 16.12.2015
comment
Спасибо за объяснение ! - person Husayn Hakeem; 17.12.2015
comment
Он генерирует PDF, когда есть только текст или абзац. Когда он содержит несколько изображений или ‹div› в html, он генерирует пустую страницу. пожалуйста, помогите - person David; 18.10.2016
comment
Привет.. Я использовал этот код для создания pdf из списка.. Сначала я преобразовал весь список в растровое изображение.. затем преобразовал это изображение в pdf.. Теперь я столкнулся с проблемой, что я получаю только одну страницу в pdf, который печатает частичное изображение.. - person ManishNegi; 22.12.2016
comment
Плагин Gradle не найден в - person Maaz Patel; 09.04.2018
comment
@BrunoLowagie в том, что iTextG — бесплатное программное обеспечение, или мне нужно получить лицензию? - person AMIT; 30.05.2019
comment
Это бесплатно только для открытого исходного кода, иначе требуется лицензия! - person Morten Holmgaard; 11.05.2020


Загрузите исходный код отсюда (Программно создайте файл PDF в Android )

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_generate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Generate PDF" />

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:id="@+id/ll_pdflayout"
        android:background="#ffffff"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/iv_image"
            android:src="@drawable/image"
            android:layout_width="300dp"
            android:scaleType="fitXY"
            android:layout_marginTop="10dp"
            android:layout_gravity="center"
            android:layout_height="250dp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="14dp"
            android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:textColor="#000000"/>


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv_link"
            android:textSize="10dp"
            android:textColor="#000000"/>


    </LinearLayout>

</LinearLayout>

MainActivity.java

package com.deepshikha.generatepdf;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.pdf.PdfDocument;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    Button btn_generate;
    TextView tv_link;
    ImageView iv_image;
    LinearLayout ll_pdflayout;
    public static int REQUEST_PERMISSIONS = 1;
    boolean boolean_permission;
    boolean boolean_save;
    Bitmap bitmap;
    ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        fn_permission();
        listener();
    }


    private void init(){
        btn_generate = (Button)findViewById(R.id.btn_generate);
        tv_link = (TextView)findViewById(R.id.tv_link);
        iv_image = (ImageView) findViewById(R.id.iv_image);
        ll_pdflayout = (LinearLayout) findViewById(R.id.ll_pdflayout);

    }

    private void listener(){
        btn_generate.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        switch (view.getId()) {
            case R.id.btn_generate:

                if (boolean_save) {
                    Intent intent = new Intent(getApplicationContext(), PDFViewActivity.class);
                    startActivity(intent);

                } else {
                    if (boolean_permission) {
                        progressDialog = new ProgressDialog(MainActivity.this);
                        progressDialog.setMessage("Please wait");
                         bitmap = loadBitmapFromView(ll_pdflayout, ll_pdflayout.getWidth(), ll_pdflayout.getHeight());
                        createPdf();
//                        saveBitmap(bitmap);
                    } else {

                    }

                    createPdf();
                    break;
                }
        }
    }

    private void createPdf(){
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics displaymetrics = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        float hight = displaymetrics.heightPixels ;
        float width = displaymetrics.widthPixels ;

        int convertHighet = (int) hight, convertWidth = (int) width;

//        Resources mResources = getResources();
//        Bitmap bitmap = BitmapFactory.decodeResource(mResources, R.drawable.screenshot);

        PdfDocument document = new PdfDocument();
        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(convertWidth, convertHighet, 1).create();
        PdfDocument.Page page = document.startPage(pageInfo);

        Canvas canvas = page.getCanvas();


        Paint paint = new Paint();
        canvas.drawPaint(paint);


        bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth, convertHighet, true);

        paint.setColor(Color.BLUE);
        canvas.drawBitmap(bitmap, 0, 0 , null);
        document.finishPage(page);


       String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/PdfTett/";
    File dir = new File(path);
    if (!dir.exists())
        dir.mkdirs();

    File filePath = new File(dir,"Testtt.pdf");

        try {
            document.writeTo(new FileOutputStream(filePath));
            btn_generate.setText("Check PDF");
            boolean_save=true;
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
        }

        // close the document
        document.close();
    }



    public static Bitmap loadBitmapFromView(View v, int width, int height) {
        Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.draw(c);

        return b;
    }

    private void fn_permission() {
        if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)||
                (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {

            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE))) {
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_PERMISSIONS);

            }

            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_PERMISSIONS);

            }
        } else {
            boolean_permission = true;


        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSIONS) {

            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                boolean_permission = true;


            } else {
                Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();

            }
        }
    }


}

Спасибо!

person Deepshikha Puri    schedule 07.06.2017
comment
при использовании вида ресайклера внутри макета длина pdf-файла равна высоте вида ресайклера. Это не включает все предметы. Как это получить? - person Lakshya Punhani; 04.02.2018
comment
Большое спасибо, ваше решение будет работать нормально, если мы укажем абсолютный путь: String targetPdf = Environment.getExternalStorageDirectory().getAbsolutePath()+/test.pdf; и создадим его, если он не существует: < б>если (!filePath.exists()) { filePath.createNewFile(); Кстати, все равно хорошая работа! - person Think Twice Code Once; 11.01.2019

Вы можете использовать ниже, как.

pdf понравится ниже..

введите здесь описание изображения

  1. activity_main.xml

<Button
    android:id="@+id/btnCreatePdf"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Create PDF" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:singleLine="true"
        android:text="Thank You!"
        android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
        android:textSize="20sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_sub_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:singleLine="true"
        android:text="Your transaction is successful"
        android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
        android:textSize="16sp" />

</LinearLayout>

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#e6e6e6" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/tv_location"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Location" />

    <TextView
        android:id="@+id/tv_city"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:text="Dhaka"
        android:textStyle="bold" />

</LinearLayout>
  1. MainActivity:

     public class MainActivity extends AppCompatActivity {
        Button btnCreatePdf;
        TextView tv_title;
        TextView tv_sub_title;
        TextView tv_location;
        TextView tv_city;
    
    
       String file_name_path = "";
       int PERMISSION_ALL = 1;
       String[] PERMISSIONS = {
    
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
        android.Manifest.permission.READ_EXTERNAL_STORAGE,
    
       };
    
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
    
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
    
         if (!hasPermissions(MainActivity.this, PERMISSIONS)) {
        ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, PERMISSION_ALL);
        }
    
          File file = new File(this.getExternalFilesDir(null).getAbsolutePath(), "pdfsdcard_location");
       if (!file.exists()) {
        file.mkdir();
    }
    
    btnCreatePdf = findViewById(R.id.btnCreatePdf);
    tv_title = findViewById(R.id.tv_title);
    tv_sub_title = findViewById(R.id.tv_sub_title);
    tv_location = findViewById(R.id.tv_location);
    tv_city = findViewById(R.id.tv_city);
    
    
     btnCreatePdf.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            createpdf();
         }
        });
    
      }
    
    
    public void createpdf() {
        Rect bounds = new Rect();
        int pageWidth = 300;
        int pageheight = 470;
        int pathHeight = 2;
    
        final String fileName = "mypdf";
         file_name_path = "/pdfsdcard_location/" + fileName + ".pdf";
        PdfDocument myPdfDocument = new PdfDocument();
        Paint paint = new Paint();
        Paint paint2 = new Paint();
        Path path = new Path();
        PdfDocument.PageInfo myPageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageheight, 1).create();
       PdfDocument.Page documentPage = myPdfDocument.startPage(myPageInfo);
       Canvas canvas = documentPage.getCanvas();
       int y = 25; // x = 10,
       int x = 10;
    
       paint.getTextBounds(tv_title.getText().toString(), 0, tv_title.getText().toString().length(), bounds);
    x = (canvas.getWidth() / 2) - (bounds.width() / 2);
    canvas.drawText(tv_title.getText().toString(), x, y, paint);
    
       paint.getTextBounds(tv_sub_title.getText().toString(), 0, tv_sub_title.getText().toString().length(), bounds);
      x = (canvas.getWidth() / 2) - (bounds.width() / 2);
      y += paint.descent() - paint.ascent();
     canvas.drawText(tv_sub_title.getText().toString(), x, y, paint);
    
      y += paint.descent() - paint.ascent();
     canvas.drawText("", x, y, paint);
    
    //horizontal line
    path.lineTo(pageWidth, pathHeight);
    paint2.setColor(Color.GRAY);
    paint2.setStyle(Paint.Style.STROKE);
    path.moveTo(x, y);
    
    canvas.drawLine(0, y, pageWidth, y, paint2);
    
    //blank space
    y += paint.descent() - paint.ascent();
    canvas.drawText("", x, y, paint);
    
    y += paint.descent() - paint.ascent();
    x = 10;
    canvas.drawText(tv_location.getText().toString(), x, y, paint);
    
    y += paint.descent() - paint.ascent();
    x = 10;
    canvas.drawText(tv_city.getText().toString(), x, y, paint);
    
    //blank space
    y += paint.descent() - paint.ascent();
    canvas.drawText("", x, y, paint);
    
    //horizontal line
    path.lineTo(pageWidth, pathHeight);
    paint2.setColor(Color.GRAY);
    paint2.setStyle(Paint.Style.STROKE);
    path.moveTo(x, y);
    canvas.drawLine(0, y, pageWidth, y, paint2);
    
    //blank space
    y += paint.descent() - paint.ascent();
    canvas.drawText("", x, y, paint);
    
    Resources res = getResources();
    Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.logo);
    Bitmap b = (Bitmap.createScaledBitmap(bitmap, 100, 50, false));
    canvas.drawBitmap(b, x, y, paint);
    y += 25;
    canvas.drawText(getString(R.string.app_name), 120, y, paint);
    
    
    myPdfDocument.finishPage(documentPage);
    
    File file = new File(this.getExternalFilesDir(null).getAbsolutePath() + file_name_path);
    try {
        myPdfDocument.writeTo(new FileOutputStream(file));
    } catch (IOException e) {
        e.printStackTrace();
    }
    
      myPdfDocument.close();
      viewPdfFile();
     }
    
    public void viewPdfFile() {
    
       File file = new File(this.getExternalFilesDir(null).getAbsolutePath() + file_name_path);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(file), "application/pdf");
       startActivity(intent);
     }
    
    
       public static boolean hasPermissions(Context context, String... permissions) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
          }
          }
       return true;
       }
    }
    
  2. Не забудьте добавить следующие разрешения в файл манифеста

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
  3. Полный исходный код Скачать с GitHub: https://github.com/enamul95/CreatePdf.git

person Enamul Haque    schedule 13.09.2020
comment
getExternalStorageDirectory() Этот метод устарел на уровне API 29. - person IntelliJ Amiya; 16.09.2020
comment
Я получаю эту ошибку.. Не удается отобразить pdf (mypdf не может быть открыт). Скопировал репозиторий github с той же ошибкой - person Amir Dora.; 23.10.2020
comment
использовали ли вы: StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); - person Enamul Haque; 23.10.2020
comment
@АмирДора. Я обновил код. я думаю, это сработает - person Enamul Haque; 28.10.2020