BOM 없이 UTF-8로 엑셀 데이터를 내보낼 수 있습니까?
Microsoft Excel 데이터를 Excel 매크로(VBScript)로 내보냅니다.파일이 루아 스크립트이기 때문에 UTF-8로 내보냅니다.내가 엑셀에서 UTF-8을 만들 수 있는 유일한 방법은 이렇게 dodb.stream을 사용하는 것입니다.
set fileLua = CreateObject("adodb.stream")
fileLua.Type = 2
fileLua.Mode = 3
fileLua.Charset = "UTF-8"
fileLua.Open
fileLua.WriteText("test")
fileLua.SaveToFile("Test.lua")
fileLua.flush
fileLua.Close
Test.lua에서 BOM을 제거하고 싶은데 방법을 모르겠습니다. (Test.lua에 유니코드 텍스트가 있어서 UTF-8 형식을 사용해야 합니다.)
엑셀 파일에 BOM 없이 UTF-8 파일을 만드는 방법을 알고 있습니까?잘 부탁드립니다.
저도 같은 문제가 있습니다. 엑셀(Office 2003, VBA6.5)에서 UTF-8 인코딩 파일로 데이터를 내보내야 합니다.질문에서 답을 찾았습니다! 아래 예에서는 BOM을 Boost의 (감사합니다!) 답변에서 #2 트릭을 사용하여 제거했습니다.저는 1등을 하지 못했고 3등을 해본 적이 없습니다.
Sub WriteUTF8WithoutBOM()
Dim UTFStream As Object
Set UTFStream = CreateObject("adodb.stream")
UTFStream.Type = adTypeText
UTFStream.Mode = adModeReadWrite
UTFStream.Charset = "UTF-8"
UTFStream.LineSeparator = adLF
UTFStream.Open
UTFStream.WriteText "This is an unicode/UTF-8 test.", adWriteLine
UTFStream.WriteText "First set of special characters: öäåñüûú€", adWriteLine
UTFStream.WriteText "Second set of special characters: qwertzuiopõúasdfghjkléáûyxcvbnm\|Ä€Í÷×äðÐ[]í³£;?¤>#&@{}<;>*~¡^¢°²`ÿ´½¨¸0", adWriteLine
UTFStream.Position = 3 'skip BOM
Dim BinaryStream As Object
Set BinaryStream = CreateObject("adodb.stream")
BinaryStream.Type = adTypeBinary
BinaryStream.Mode = adModeReadWrite
BinaryStream.Open
'Strips BOM (first 3 bytes)
UTFStream.CopyTo BinaryStream
'UTFStream.SaveToFile "d:\adodb-stream1.txt", adSaveCreateOverWrite
UTFStream.Flush
UTFStream.Close
BinaryStream.SaveToFile "d:\adodb-stream2.txt", adSaveCreateOverWrite
BinaryStream.Flush
BinaryStream.Close
End Sub
사용한 ADO Stream Object 참조입니다.
adTypeText 상수로 인해 어려움을 겪고 있는 다른 사용자가 있다면, 도구->참조 아래에 "Microsoft ActiveX Data Objects 2.5 Object Library"를 포함해야 합니다.
몇 가지 가능성:
버퍼에 텍스트를 UTF-8, Type=2로 입력한 다음 Type=1(2진수)을 설정하고 기록합니다.ADODB를 설득할 수도 있습니다.BOM 추가를 건너뛸 스트림입니다.
binary를 입력하여 다른 버퍼를 만들고 CopyTo를 사용하여 BOM 다음 지점에서 해당 버퍼로 데이터를 복사합니다.
스크립팅을 사용하여 파일을 다시 읽습니다.FileSystemObject, BOM 잘라내기, 다시 쓰기
편집
rellampec의 의견은 사용자 272735의 방법으로 파일 끝에 추가된 LF를 삭제하는 더 나은 방법을 알려주었습니다.마지막에 새로운 버전의 루틴을 추가했습니다.
원본 게시물
저는 1년 동안 user272735의 메소드를 성공적으로 사용하고 있었는데 파일 끝에 LF가 추가되어 있는 것을 발견했습니다.제가 아주 상세한 테스트를 하기 전까지는 이 추가 LF를 알아차리지 못했기 때문에 이것은 중요한 오류가 아닙니다.하지만 제 최신 버전은 LF가 중요해질 경우를 대비해 폐기합니다.
Public Sub PutTextFileUtf8(ByVal PathFileName As String, ByVal FileBody As String)
' Outputs FileBody as a text file (UTF-8 encoding without leading BOM)
' named PathFileName
' Needs reference to "Microsoft ActiveX Data Objects n.n Library"
' Addition to original code says version 2.5. Tested with version 6.1.
' 1Nov16 Copied from http://stackoverflow.com/a/4461250/973283
' but replaced literals with parameters.
' 15Aug17 Discovered routine was adding an LF to the end of the file.
' Added code to discard that LF.
' References: http://stackoverflow.com/a/4461250/973283
' https://www.w3schools.com/asp/ado_ref_stream.asp
Dim BinaryStream As Object
Dim UTFStream As Object
Set UTFStream = CreateObject("adodb.stream")
UTFStream.Type = adTypeText
UTFStream.Mode = adModeReadWrite
UTFStream.Charset = "UTF-8"
' The LineSeparator will be added to the end of FileBody. It is possible
' to select a different value for LineSeparator but I can find nothing to
' suggest it is possible to not add anything to the end of FileBody
UTFStream.LineSeparator = adLF
UTFStream.Open
UTFStream.WriteText FileBody, adWriteLine
UTFStream.Position = 3 'skip BOM
Set BinaryStream = CreateObject("adodb.stream")
BinaryStream.Type = adTypeBinary
BinaryStream.Mode = adModeReadWrite
BinaryStream.Open
UTFStream.CopyTo BinaryStream
' Oriinally I planned to use "CopyTo Dest, NumChars" to not copy the last
' byte. However, NumChars is described as an integer whereas Position is
' described as Long. I was concerned by "integer" they mean 16 bits.
'Debug.Print BinaryStream.Position
BinaryStream.Position = BinaryStream.Position - 1
BinaryStream.SetEOS
'Debug.Print BinaryStream.Position
UTFStream.Flush
UTFStream.Close
Set UTFStream = Nothing
BinaryStream.SaveToFile PathFileName, adSaveCreateOverWrite
BinaryStream.Flush
BinaryStream.Close
Set BinaryStream = Nothing
End Sub
루틴의 새 버전
이 버전에서는 처음에 LF를 추가하지 않기 때문에 마지막에 추가된 원하지 않는 LF를 삭제하는 코드를 생략합니다.후행 문자 삭제 기술에 관심이 있는 사람이 있을 경우를 대비해 원본을 보관해 두었습니다.
Public Sub PutTextFileUtf8NoBOM(ByVal PathFileName As String, ByVal FileBody As String)
' Outputs FileBody as a text file named PathFileName using
' UTF-8 encoding without leading BOM
' Needs reference to "Microsoft ActiveX Data Objects n.n Library"
' Addition to original code says version 2.5. Tested with version 6.1.
' 1Nov16 Copied from http://stackoverflow.com/a/4461250/973283
' but replaced literals with parameters.
' 15Aug17 Discovered routine was adding an LF to the end of the file.
' Added code to discard that LF.
' 11Oct17 Posted to StackOverflow
' 9Aug18 Comment from rellampec suggested removal of adWriteLine from
' WriteTest statement would avoid adding LF.
' 30Sep18 Amended routine to remove adWriteLine from WriteTest statement
' and code to remove LF from file. Successfully tested new version.
' References: http://stackoverflow.com/a/4461250/973283
' https://www.w3schools.com/asp/ado_ref_stream.asp
Dim BinaryStream As Object
Dim UTFStream As Object
Set UTFStream = CreateObject("adodb.stream")
UTFStream.Type = adTypeText
UTFStream.Mode = adModeReadWrite
UTFStream.Charset = "UTF-8"
UTFStream.Open
UTFStream.WriteText FileBody
UTFStream.Position = 3 'skip BOM
Set BinaryStream = CreateObject("adodb.stream")
BinaryStream.Type = adTypeBinary
BinaryStream.Mode = adModeReadWrite
BinaryStream.Open
UTFStream.CopyTo BinaryStream
UTFStream.Flush
UTFStream.Close
Set UTFStream = Nothing
BinaryStream.SaveToFile PathFileName, adSaveCreateOverWrite
BinaryStream.Flush
BinaryStream.Close
Set BinaryStream = Nothing
End Sub
uf 외부 코드 대신 네이티브 T-SQL을 선호합니다.
DECLARE @FILE_NAME VARCHAR(255) = 'd:\utils\test.xml' --drive:\path\filename\
DECLARE @FILE_DATA VARCHAR(MAX) = '<?xml version="1.0" encoding="UTF-8"?>test</xml>' --binary as varchar(max)
DECLARE @FILE_NAME_TO VARCHAR(255) --Temp name for text stream
DECLARE @FSO_ID_TXTSTRM INT --Text Stream
DECLARE @FSO_ID_BINSTRM INT --Binary Stream
DECLARE @RC INT
EXEC @RC = sp_OACreate 'ADODB.Stream', @FSO_ID_TXTSTRM OUTPUT
EXEC @RC = sp_OASetProperty @FSO_ID_TXTSTRM, 'Type', 2 --1 = binary, 2 = text
EXEC @RC = sp_OASetProperty @FSO_ID_TXTSTRM, 'Mode', 3 --0 = not set, 1 read, 2 write, 3 read/write
EXEC @RC = sp_OASetProperty @FSO_ID_TXTSTRM, 'Charset', 'UTF-8' --'ISO-8859-1'
EXEC @RC = sp_OASetProperty @FSO_ID_TXTSTRM, 'LineSeparator', 'adLF'
EXEC @RC = sp_OAMethod @FSO_ID_TXTSTRM, 'Open'
EXEC @RC = sp_OAMethod @FSO_ID_TXTSTRM, 'WriteText', NULL, @FILE_DATA --text method
--Create binary stream
EXEC @RC = sp_OACreate 'ADODB.Stream', @FSO_ID_BINSTRM OUTPUT
EXEC @RC = sp_OASetProperty @FSO_ID_BINSTRM, 'Type', 1 --1 = binary, 2 = text
EXEC @RC = sp_OAMethod @FSO_ID_BINSTRM, 'Open'
EXEC @RC = sp_OASetProperty @FSO_ID_BINSTRM, 'Mode', 3 --0 = not set, 1 read, 2 write, 3 read/write
--Move 3 positions forward in text stream (BOM is first 3 positions)
EXEC @RC = sp_OASetProperty @FSO_ID_TXTSTRM, 'Position', 3
--Copy text stream to binary stream
EXEC @RC = sp_OAMethod @FSO_ID_TXTSTRM, 'CopyTo', NULL, @FSO_ID_BINSTRM
--Commit data and close text stream
EXEC @RC = sp_OAMethod @FSO_ID_TXTSTRM, 'Flush'
EXEC @RC = sp_OAMethod @FSO_ID_TXTSTRM, 'Close'
EXEC @RC = sp_OADestroy @FSO_ID_TXTSTRM
--Save binary stream to file and close
EXEC @RC = sp_OAMethod @FSO_ID_BINSTRM, 'SaveToFile', NULL, @FILE_NAME, 2 --1 = notexist 2 = overwrite
EXEC @RC = sp_OAMethod @FSO_ID_BINSTRM, 'Close'
EXEC @RC = sp_OADestroy @FSO_ID_BINSTRM
질문과 중복되는 답변에서 또 다른 BOM 폐기 해킹이 있습니다.
답변이 늦어서 죄송합니다 - 바이트 주문 마커를 접하는 다른 사람들을 위한 것입니다 - 이 질문에 대한 페이지 뷰는 질문이 몇 가지 관련 문제와 관련이 있음을 알려줍니다. VBA에서 BOM-Free 파일을 작성하는 것은 놀라울 정도로 어렵습니다. - 일부 일반 스트림 라이브러리에서도 출력에 BOM을 저장합니다.당신이 그것을 요구했든 아니든.
아래의 코드가 약간 다른 문제를 해결하고 있기 때문에 '중복'이라고 답합니다. - 이기종 파일 모음이 있는 폴더에 스키마 파일을 쓰는 것이 주된 목적이지만, BOM 제거 및 BOM이 없는 파일 쓰기가 사용 중인 작업 예제이며, 관련 세그먼트가 명확하게 표시되어 있습니다.
핵심 기능은 폴더의 모든 '.csv' 파일을 반복하고 각 파일을 처음 4바이트의 빠른 니블로 테스트하는 것입니다. 마커가 발견되면 마커를 제거하는 작업만 수행합니다.
우리는 원시 C의 낮은 수준의 파일 처리 코드로 작업하고 있습니다.우리는 바이트 배열을 사용하는 것까지 해야 합니다. 왜냐하면 VBA에서 하는 다른 모든 것들은 문자열 변수의 구조에 내장된 바이트 순서 마커를 저장하기 때문입니다.
그래서, 더 이상의 오류 없이, 코드는 다음과 같습니다:
BOM-schema.ini 파일의 텍스트 파일에 대한 폐기 코드:
strFolder As String (strFolder As String)다음에 오류가 다시 시작될 때
Schema.ini 파일을 데이터 폴더에 씁니다.
이는 다음을 설정할 레지스트리 권한이 없는 경우에 필요합니다.올바른 '혼합 유형 가져오기=IMEX=1을 재정의하는 Text' 레지스트리 값
으로 CharacterSet(UNICODE할 수 설정 ' 코는또 ANSI 또는 UTF-8 및 UTF-16 .'끔찍한 해킹으로 문자 집합(UNICODE|ANSI)에 사용할 수 있는 설정입니다.
코드 되지 않습니다. 합니다. OEM 드습정텍지원않지니. 추가 코딩이 필요합니다.
... 파일의 수 .' 텍스트 파일 공급자는 UTF-16 또는 UTF-8 파일의 BOM을 처리할 수 없습니다.
구현되지 않음: 탭으로 구분된 파일 또는 기타 구분 기호를 처리합니다.그코드는 열이 있는 헤더 행을 가정하고 '모든 행 검색'을 지정합니다.는 데이터 유형이 혼합된 경우 '열을 텍스트로 읽기'를 부과합니다.
문자열로서의 DimstrSchemaDimstr 파일을 문자열로 지정길이만큼 파일 조임Dimar 파일()을 바이트로 지정바이트로 사용하는 2진수 바이트(0에서 4로)
If Right(strFolder, 1) <> "\" ThenstFolder = strFolder & "\"
Dir()는 와일드카드로 호출할 때 반복 함수입니다.
strFile = VBA.파일 시스템.Dir(strFolder & "*.csv")
렌(strFile) 중 작업 수행 > 0
hndFile = 여유 파일#hndFile로 이진에 대한 strFolder & strFile 열기#hndFile , ,arBytes 가져오기#hndFile 닫기
strSchema = strSchema & [" & strFile & "] & vbCrLfstrSchema = strSchema & "Format="CSVD 제한" 및 vbCrLfstrSchema = strSchema & "혼합 유형= 텍스트 가져오기" & vbCrLfstrSchema = strSchema & "MaxScanRows=0" & vbCrLf
arrBytes(2) = 0 OrarBytes(3) = 0이면 '이것은 해킹입니다.strSchema = strSchema & "문자세트=DICR" & vbCrLf또 다른strSchema = strSchema & "문자세트 = ANSI" & vbCrLf종료할 경우
strSchema = strSchema & "ColNameHeader = True" & vbCrLfstrSchema = strSchema & vbCrLf
' ***********************************************************
BOM 폐기 - 바이트 순서 표시가 OLEDB 액세스 텍스트 공급자를 구분합니다.
if arBytes(0) = &HFE AndarBytes(1) = &HFF _OrarBytes(0) = &HFF 및 ArrBytes(1) = &HFE 다음
hndFile = 여유 파일#hndFile 이 로 strFolder & strFile 기0 To LOF - )ReDimar 일파0(0 To LOF(hndFile) - # , 가져오기hndFile , ,arRFile 파일 # #hndFile 파일 닫기
& "" "BigReplacearFile, arBytes(0) 및 arBytes(1), "
hndFile = 여유 파일#hndFile 이 에 strFolder & strFile기 열 Put # ,#hndFile , ,arRFile #닫기#hndFile 닫 ErasearFilear arr arr
&= &= & 그 다음에 ElseIfarBytes(0) = &HEF AndarBytes(1) = &HBF 및 ArBytes(2) = &HBF
hndFile = 여유 파일#hndFile 이 로 strFolder & strFile 기0 To LOF - )ReDimar 일파0(0 To LOF(hndFile) - # , 가져오기#hndFile , ,arRFile 닫기 ##hndFile & & " " " BigReplacearFile, arBytes(0) & arBytes(1) & arBytes(2), "
hndFile = 여유 파일#hndFile 이 에 strFolder & strFile기 열 Put # ,#hndFile , ,arRFile #닫기#hndFile 닫 ErasearFilear arr arr
종료할 경우
' ***********************************************************
strFile = " " = Dir = Dir
고
> 인 경우 렌(strSchema) > 0인 경우
= & " strFile = strFolder & "Schema.ini"
hndFile = 여유 파일, #hndFile , , strSchema치 닫기 # #hndFile 기
종료할 경우
끝 하위 항목
공하위큰바기꾸바이로트 (ByRefBytes() 용▁_,로)▁by, Search _문열로참조색검, With 기준: 문자열로 대체)다음에 오류가 다시 시작될 때
변종 DimvarSplit As 형변
varSplit 분할대(ARRBytes, 검상색) = arBytes = 조인$(varSplit, 대체)
varSplit 지우기
끝 하위 항목
바이트 배열을 VBA에 할당할 수 있다는 것을 알면 코드를 더 쉽게 이해할 수 있습니다.문자열 또는 그 반대입니다.BigReplace() 기능은 VBA의 비효율적인 문자열 처리, 특히 할당을 회피하는 해킹입니다. 다른 방법으로 하면 대용량 파일이 심각한 메모리 및 성능 문제를 야기한다는 것을 알게 될 것입니다.
언급URL : https://stackoverflow.com/questions/4143524/can-i-export-excel-data-with-utf-8-without-bom
'programing' 카테고리의 다른 글
Pymongo 결과에서 _id 요소 제거 (0) | 2023.05.18 |
---|---|
Ctrl-스페이스를 누르지 않은 이클립스의 Ctrl-스페이스 (0) | 2023.05.18 |
NPM 패키지의 종속성, devDependencies 및 peerDependencies의 차이점은 무엇입니까?json 파일? (0) | 2023.05.18 |
UI 이미지 자르기 (0) | 2023.05.18 |
SQL Server JOIN에 NULL 값이 누락되었습니다. (0) | 2023.05.18 |