读书人

用API打印有关问题:为什么只能打选取

发布时间: 2012-01-16 23:36:51 作者: rapoo

用API打印问题:为什么只能打选取的.txt文件,不能打word,excel,html等,我是向打印机输出byte[]啊
选取.txt文本文件打没有问题,但是选取word等文件打出来得就是乱码!!我是向打印机输出byte[]啊。。为什么。。

请高手指点。


using System;
using System.IO;
using System.Drawing.Printing;
using System.Runtime.InteropServices;

namespace XXL.Tools
{

public class PrintingUtil
{

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct DOCINFOW
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDataType;
}

[DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = false,
CallingConvention = CallingConvention.StdCall)]
public static extern long OpenPrinter(string pPrinterName, ref IntPtr phPrinter, int pDefault);

//[DllImport("winspool.Drv", EntryPoint = "OpenPrinterW",
// CharSet = CharSet.Unicode, SetLastError = true,
// ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
//static extern bool OpenPrinter(string src, ref IntPtr hPrinter, long pd);

[DllImport("winspool.Drv", EntryPoint = "ClosePrinter",
CharSet = CharSet.Unicode, SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern bool ClosePrinter(IntPtr hPrinter);

[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterW",
CharSet = CharSet.Unicode, SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern bool StartDocPrinter(IntPtr hPrinter,
int level, ref DOCINFOW pDI);

[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter",
CharSet = CharSet.Unicode, SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern bool EndDocPrinter(IntPtr hPrinter);

[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter",
CharSet = CharSet.Unicode, SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern bool StartPagePrinter(IntPtr hPrinter);

[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter",
CharSet = CharSet.Unicode, SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern bool EndPagePrinter(IntPtr hPrinter);

[DllImport("winspool.Drv", EntryPoint = "WritePrinter",
CharSet = CharSet.Unicode, SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern bool WritePrinter(IntPtr hPrinter,
IntPtr pBytes, int dwCount, ref int dwWritten);


//SendBytesToPrinter()
//When the function is given a printer name and an unmanaged array of
//bytes, the function sends those bytes to the print queue.
//Returns True on success or False on failure.
public bool SendBytesToPrinter(string szPrinterName,
IntPtr pBytes, int dwCount)


{
// The printer handle.
IntPtr hPrinter = new IntPtr(0);
// Last error - in case there was trouble.
int dwError;
// Describes your document (name, port, data type).
DOCINFOW di = new DOCINFOW();
// The number of bytes written by WritePrinter().
int dwWritten = 0;
// Your success code.
bool bSuccess;

// Set up the DOCINFO structure.
di.pDocName = "My C# .NET RAW Document";
di.pDataType = "RAW";
// Assume failure unless you specifically succeed.
bSuccess = false;
if (Convert.ToBoolean( OpenPrinter(szPrinterName, ref hPrinter, 0) ))//modified by XXL
{
if (StartDocPrinter(hPrinter, 1, ref di))
{
if (StartPagePrinter(hPrinter))
{
// Write your printer-specific bytes to the printer.
bSuccess = WritePrinter(hPrinter, pBytes,
dwCount, ref dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}



public bool SendFileToPrinter(string szPrinterName, string szFileName)
{
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes large enough to hold the file's contents.
byte[] bytes = new byte[fs.Length];
bool bSuccess;
// Your unmanaged pointer
IntPtr pUnmanagedBytes;

// Read the contents of the file into the array.
bytes = br.ReadBytes(Convert.ToInt32(fs.Length));
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(Convert.ToInt32(fs.Length));
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, Convert.ToInt32(fs.Length));
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName,
pUnmanagedBytes, Convert.ToInt32(fs.Length));
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);

br.Close();//by XXL
fs.Close();//by XXL

return bSuccess;
}


public bool SendStringToPrinter(string szPrinterName, string szString)
{
bool bSuccess;
IntPtr pBytes = new IntPtr(0);
int dwCount;
//How many characters are in the string?
dwCount = szString.Length;
//Assume that the printer is expecting ANSI text, and then convert


//the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
//Send the converted ANSI string to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pBytes, dwCount);

Marshal.FreeCoTaskMem(pBytes);
return bSuccess;
}
}
}

[解决办法]
你调用API打印出的效果 就是记事本显示的效果。你BYTE[] 得到的 BYTE 不是文本信息 里面有WORD文件头 和WORD的文件信息,打印出来就看不明白了。
[解决办法]
WORD的文件中有大量的控制字符,当然不一样啦

读书人网 >C#

热点推荐