2017-10-09 47 views
2

我是編碼世界的完整初學者,我嘗試使用IText從我的應用程序生成PDF。我設法創建了基本的PDF文本,表格等。 現在我想從已經創建而不是空的數據庫檢索數據。 我查看了StackOverflow和Internet上的許多主題,但無法使其工作。使用Itext顯示PDF格式的SQLite數據庫的結果

任何幫助將受到歡迎

請讓我知道如果你需要任何東西,並在此先感謝!

這裏是我的代碼:

ReportActivity

public class ReportActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_report); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    //getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
} 

public void onClick_report(View view) { 
    try { 
     createPdf(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (DocumentException e) { 
     e.printStackTrace(); 
    } 

} 

private void createPdf() throws FileNotFoundException, DocumentException { 

    File pdfFolder = new File(getExternalFilesDir("report"), "report"); 
    Date date = new Date(); 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date); 
    File myFile = new File(pdfFolder + timeStamp + ".pdf"); 
    OutputStream output = new FileOutputStream(myFile); 

    DatabaseHandler db = new DatabaseHandler(getApplicationContext()); 
    Cursor cursor = db.getSepficItem(); 

    //Step 1 
    Document document = new Document(); 

    //Step 2 
    PdfWriter.getInstance(document, output); 

    //Step 3 
    document.open(); 

    //Step 4 Add content 

    PdfPTable table = new PdfPTable(6); 

    table.addCell("id col"); 
    table.addCell("day col"); 
    table.addCell("month col"); 
    table.addCell("Year col"); 
    table.addCell("type col"); 
    table.addCell("amount col"); 
    table.addCell("comment col"); 
    table.addCell("photo col"); 
    table.addCell("cust col"); 

    cursor.moveToFirst(); 
    int count = cursor.getCount(); 

    for (int j = 0; j < count; j++) 
    { 
     table.addCell(cursor.getString(cursor.getColumnIndex("id"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("day"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("month"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("year"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("type"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("amount"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("comment"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("photo"))); 
     table.addCell(cursor.getString(cursor.getColumnIndex("customername"))); 

     cursor.moveToNext(); 
    } 

    //Step 5: Close the document 
    document.close(); 
} 

DataBaseHelper:

public class DatabaseHandler extends SQLiteOpenHelper { 
private static final int DATABASE_VERSION = 18; 
private static final String DATABASE_NAME = "ExpenseNote"; 

//Table Customer 
private static final String TABLE_CUST = "Customer"; 
private static final String CUST_ID = "id"; 
private static final String CUST_NAME = "name"; 

//Table Expense 
private static final String TABLE_EXPENSE = "Expense"; 
private static final String EXPENS_ID = "id"; 
private static final String EXPENS_DAY = "day"; 
private static final String EXPENS_MONTH = "month"; 
private static final String EXPENS_YEAR = "year"; 
private static final String EXPENS_TYPE = "type"; 
private static final String EXPENS_AMOUNT = "amount"; 
private static final String EXPENS_COMMENT = "comment"; 
private static final String EXPENS_PHOTO = "photo"; 
private static final String EXPENS_CUST = "customername"; 


public DatabaseHandler(Context context) { 
    super(context, DATABASE_NAME, null, DATABASE_VERSION); 
} 

// Creating Tables 
@Override 
public void onCreate(SQLiteDatabase db) { 
    // Category table create query 
    String CREATE_ITEM_TABLE = "CREATE TABLE IF NOT EXISTS " 
      + TABLE_CUST + "(" 
      + CUST_ID + " integer primary key," 
      + CUST_NAME + " text not null)"; 
    db.execSQL(CREATE_ITEM_TABLE); 

    String CREATE_EXPENSE_TABLE = "CREATE TABLE IF NOT EXISTS " 
      + TABLE_EXPENSE + "(" 
      + EXPENS_ID + " integer PRIMARY KEY," 
      + EXPENS_DAY + " integer," 
      + EXPENS_MONTH + " integer," 
      + EXPENS_YEAR + " integer," 
      + EXPENS_TYPE + " text," 
      + EXPENS_AMOUNT + " real," 
      + EXPENS_COMMENT + " text," 
      + EXPENS_PHOTO + " text," 
      + EXPENS_CUST + " text)"; 
    // + " FOREIGN KEY (" + CUST_ID + ") REFERENCES " + TABLE_CUST + "(" + CUST_ID + "));"; 
    db.execSQL(CREATE_EXPENSE_TABLE); 

} 


public Cursor getSepficItem(){ 
    // Select All Query 
    SQLiteDatabase db = this.getReadableDatabase(); 
    String q = "SELECT * FROM Expense"; 
    Cursor mCursor = db.rawQuery(q, null); 
    // closing connection 
    mCursor.close(); 
    db.close(); 

    // returning customer 
    return mCursor; 
} 

的logcat:

FATAL EXCEPTION: main java.lang.IllegalStateException: Could not execute method for android:onClick 
     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293) 
     at android.view.View.performClick(View.java:5610) 
     at android.view.View$PerformClick.run(View.java:22265) 
     at android.os.Handler.handleCallback(Handler.java:751) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:154) 
     at android.app.ActivityThread.main(ActivityThread.java:6077) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 
    Caused by: java.lang.reflect.InvocationTargetException 
     at java.lang.reflect.Method.invoke(Native Method) 
     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
     at android.view.View.performClick(View.java:5610)  
     at android.view.View$PerformClick.run(View.java:22265)  
     at android.os.Handler.handleCallback(Handler.java:751)  
     at android.os.Handler.dispatchMessage(Handler.java:95)  
     at android.os.Looper.loop(Looper.java:154)  
     at android.app.ActivityThread.main(ActivityThread.java:6077)  
     at java.lang.reflect.Method.invoke(Native Method)  
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)  
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)  
    Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT * FROM Expense 
     at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55) 
     at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58) 
     at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143) 
     at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132) 
     at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:219) 
     at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:258) 
     at lu.digitalsecurity.expensenote.ReportActivity.createPdf(ReportActivity.java:89) 
     at lu.digitalsecurity.expensenote.ReportActivity.onClick_report(ReportActivity.java:35) 
     at java.lang.reflect.Method.invoke(Native Method)  
     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)  
     at android.view.View.performClick(View.java:5610)  
     at android.view.View$PerformClick.run(View.java:22265)  
     at android.os.Handler.handleCallback(Handler.java:751)  
     at android.os.Handler.dispatchMessage(Handler.java:95)  
     at android.os.Looper.loop(Looper.java:154)  
     at android.app.ActivityThread.main(ActivityThread.java:6077)  
     at java.lang.reflect.Method.invoke(Native Method)  
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)  
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)  

編輯的要求:

XML文件(僅適用於當下一個簡單的按鈕):

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
app:layout_behavior="@string/appbar_scrolling_view_behavior" 
tools:context=".ReportActivity" 
tools:showIn="@layout/activity_report"> 
<Button 
    android:id="@+id/button" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Button" 
    app:layout_constraintTop_toTopOf="parent" 
    android:layout_marginTop="45dp" 
    android:layout_marginLeft="50dp" 
    app:layout_constraintLeft_toLeftOf="parent" 
    android:layout_marginRight="50dp" 
    app:layout_constraintRight_toRightOf="parent" 
    android:onClick="onClick_report"/> 

+0

發表您的活動XML和活動代碼 – akhilesh0707

+0

評論'mCursor.close();'getSepficItem() – akhilesh0707

+0

不得關閉遊標也不數據庫中,直到與完成其他遊標(你現在知道)。刪除2行'mCursor.close(); db.close();'getSepficItem'方法。 – MikeT

回答

2

那麼實際上堆棧不告訴你的錯誤是:「試圖重新打開一個已關閉的對象「。

當你做mCursor.close()基本上你說的系統「我不會再使用它了,你可以免費獲得相關資源」。

恕我直言,你應該有一個類消費,看起來像:

public class Expense { 
    private int id, day, month, year; 
    private String type; 
    // and so on... 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 
    // Other getters/setters 

} 

而且你的方法getSepficItem()應該返回一個列表:

public List<Expense> getSepficItem() { 
    List<Expense> result = new ArrayList(); 
    // Select All Query 
    SQLiteDatabase db = this.getReadableDatabase(); 
    String q = "SELECT * FROM Expense"; 
    Cursor mCursor = db.rawQuery(q, null); 
    if (cursor.moveToFirst()) { 
     do { 
      Expense expense = new Expense(); 
      expense.setId(Integer.parseInt(cursor.getString(0))); 
      // etc... 
      expense.setType(cursor.getString(2)); 
      // etc... 
      result.add(contact); 
     } while (cursor.moveToNext()); 
    } 
    mCursor.close(); 
    db.close(); 
    return result; 
} 

的生成的PDF應該使用費用的方法,而不是光標。

請注意,它不是您的具體問題的完整解決方案,而是關於如何組織代碼的線索。

最後適應PDF創建:

createPdf() { 

    for (Expense expense : db.getSepficItem()) { 
    // .. 
    table.addCell(expense.getId()); 
    } 
} 
+0

那麼這比處理光標更容易...看到我更新的答案。 – Benoit

+0

感謝您的建議,但現在我完全不知道如何使用它來解決我的問題。 我可以請你幫我解釋一下這方面的更多細節嗎? – Pyr0

+0

好吧,我剛剛更新了我的答案。再一次,它不是一個完整的解決方案,只能找到正確的方向。 – Benoit

相關問題